【问题标题】:How to cast an object for a method call?如何为方法调用转换对象?
【发布时间】:2011-12-14 22:18:53
【问题描述】:

我有以下类层次结构:

public class AI {
    public AI() { }
    public virtual void Update(float frameTime) { }
}

public class Boss : AI {
    public Boss() : base() { }
    public override void Update(float frameTime) { 
        Console.WriteLine("Boss Update"); 
    }
}

我有一个持有 AI 变量的角色,然后我在其中存储一个 Boss 实例并尝试将其转换为获取 Boss 的更新函数而不是基类的函数。

AI ai = new Boss();
(Boss)ai.Update(0f);

但这不起作用,在 C# 中执行此操作的正确方法是什么?它与另一个 AI 类正常工作,我什至根本没有 来投射它,它只是运行了正确版本的更新,所以我一定是无意中改变了一些东西。

【问题讨论】:

  • 调用 Boss 类上的 Update 方法不需要强制转换,因为您已在 AI 类中将该方法标记为 virtual,并且您已在老板班。顺便说一句,我注意到您发布的代码无法编译。
  • @Ed S.:代码示例应该是这些难题之一。 Find all of the things that are wrong with this picture.
  • @JasonDown:是的,我们都从某个地方开始。我根本没有“得到”多态性,直到我有一个真实世界的用例和随后的“啊哈!”片刻。当简单地告诉它是什么时,它非常抽象且难以理解。有点像向盲人解释壮丽的景色。只是不一样。
  • 这只是代码的简化版本,因此询问起来更简单,因此告诉我我在任意代码上打错了也无济于事。 @博士。 Wily 的学徒:它在实际代码中被覆盖,但它仍然运行 AI.Update() 而不是 Boss.Update()。它给我的问题是它运行的是基本的Update 而不是Boss 版本。
  • @Shawn:嗯,您作为示例发布的代码实际上非常相关,如果您的示例代码在语义上与您的真实代码相同,那么肯定会调用 Boss.Update,所以显然这个例子是不够的。除了使用您自己的示例之外,我们如何假定知道什么是相关的和不相关的?

标签: c# methods casting


【解决方案1】:

dot operator 具有 higher precedence 而非强制转换,因此您的代码被解释为:

(Boss)(ai.Update(frameTime));

你需要多加一对括号才能得到你想要的:

((Boss)ai).Update(frameTime);

但是,由于您的方法是虚拟的,因此不必执行此强制转换。

您可能还想考虑将AI 类型更改为abstract class 或(如果可能)接口。

【讨论】:

  • 当然,因为Update 是虚拟的并且在Boss 类中被覆盖,所以根本不需要演员表。
【解决方案2】:

您需要在强制转换和强制转换对象周围添加括号以调用强制转换值(即((SomeType)someObj).SomeMethod())的方法,但这不是重点,因为完全不需要强制转换。

Update 是虚拟的,并且调用是多态的,所以即使ai 变量被声明为AI 的实例,它实际上也会调用Boss.Update(),因为这就是幕后真正的类型。

这正是多态性强大的原因。您不必知道底层类型是什么即可获得正确的、特定于实现的行为。

【讨论】:

  • +1 详细了解为什么不需要演员表。
  • 你 +1。是时候 kybosh 我自己的答案了(你的一个不充分的版本!)。
【解决方案3】:

你的代码行是什么意思:

AI ai = new Boss();
(Boss)ai.Update();

获取从Update(); 返回的内容并将其转换为类型Boss

你需要做的是

AI ai = new Boss();
((Boss)ai).Update();

ai 转换为 Boss 并调用 Update() 方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-22
    • 1970-01-01
    • 2016-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多