简体   繁体   English

如何向下转换为重载方法

[英]How to Downcast to an Overloaded Method

I have a slight problem in my code here I think is interesting: 我的代码中有一个小问题,我认为这很有趣:

foreach(ISceneNode node in (root as IGroupNode))
            {
                PreVisit(node);
                if (notFound == false)
                {
                    return node;
                }
                else
                    PostVisit(node);
            }

I'm trying to call the methods PreVisit and PostVisit on the ISceneNode object node, which is a parent class to other types of nodes. 我试图在ISceneNode对象节点上调用方法PreVisit和PostVisit,该节点是其他类型节点的父类。 However, because this is "too general" of an object relationship, I am not allowed to call the methods: 但是,由于这是对象关系的“太笼统”,因此不允许调用这些方法:

//methods
void PreVisit(IDrawableNode drawable)
    {
        string targetName = drawable.Name;
        Boolean notFound = true;
        CompareToTarget(targetName, notFound, drawable);
    }

    void PreVisit(ITransformNode transform)
    {
        string targetName = transform.Name;
        Boolean notFound = true;
        CompareToTarget(targetName, notFound, transform);
    }

    void PreVisit(IStateNode state)
    {
        string targetName = state.Name;
        Boolean notFound = true;
        CompareToTarget(targetName, notFound, state);
    }

    void PreVisit(IGroupNode group)
    {
        string targetName = group.Name;
        Boolean notFound = true;
        CompareToTarget(targetName, notFound, group);
    }

The IGroupNode, IStateNode, etc derive from the ISceneNode... so why can't I call this overloaded method using just an ISceneNode? IGroupNode,IStateNode等是从ISceneNode派生的...为什么我不能仅使用ISceneNode来调用此重载方法? Is it because it doesn't know which method to select? 是否因为不知道选择哪种方法? How can I account for this in my code and workaround it? 如何在我的代码中说明此问题并解决该问题?

When you call your method, the object is ISceneNode, as you did not define a PreVisit(ISceneNode), it will fail to find a suitable method. 当您调用方法时,对象是ISceneNode,因为您没有定义PreVisit(ISceneNode),所以它将找不到合适的方法。

The compiler will not be able to understand that you already defined a subcase for each subtype. 编译器将无法理解您已经为每个子类型定义了一个子案例。 One solution would be to cast it to check if your object implement one of the sub interfaces and call the method on the casted object. 一种解决方案是将其强制转换以检查您的对象是否实现了子接口之一,并在强制转换的对象上调用方法。

Of course, this is not really a good solution to just write this in the middle of the rest of the code. 当然,仅在其余代码中间编写此代码并不是一个很好的解决方案。 As SLaks mention you should use a dispatch, like here , or using C# 4.0 keyword dynamic as shown here 作为SLaks何况你应该使用派遣,像这里 ,或使用C#4.0关键字dynamic如图所示这里

Here is the example of the second link: 这是第二个链接的示例:

class Animal 
{ 
}

class Cat : Animal 
{ 
}

class Dog : Animal 
{ 
}

Here are the specialisations: 以下是专长:

void ReactSpecialization(Animal me, Animal other) 
{ 
    Console.WriteLine("{0} is not interested in {1}.", me, other); 
}

void ReactSpecialization(Cat me, Dog other) 
{ 
    Console.WriteLine("Cat runs away from dog."); 
}

void ReactSpecialization(Dog me, Cat other) 
{ 
    Console.WriteLine("Dog chases cat."); 
}

Now this is how you define the double dispatch in C# 4.0 using dynamic : 现在,这就是您使用dynamic在C#4.0中定义双重分发的方式:

void React(Animal me, Animal other) 
{ 
    ReactSpecialization(me as dynamic, other as dynamic); 
}

Then run 然后跑

void Test() 
{ 
    Animal cat = new Cat(); 
    Animal dog = new Dog(); 

    React(cat, dog); 
    React(dog, cat); 
}

C# dynamic does that nicely: C# dynamic很好:

PreVisit((dynamic)node);

That select the appropriate method at runtime using C# semantics. 那将在运行时使用C#语义选择适当的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM