C# 如何向下转换到重载方法

C# 如何向下转换到重载方法,c#,relationship,downcast,C#,Relationship,Downcast,我的代码中有一个小问题,我认为这很有趣: foreach(ISceneNode node in (root as IGroupNode)) { PreVisit(node); if (notFound == false) { return node; } else

我的代码中有一个小问题,我认为这很有趣:

foreach(ISceneNode node in (root as IGroupNode))
            {
                PreVisit(node);
                if (notFound == false)
                {
                    return node;
                }
                else
                    PostVisit(node);
            }
我试图在ISceneNode对象节点上调用PreVisit和PostVisit方法,它是其他类型节点的父类。但是,由于对象关系过于笼统,因此不允许我调用以下方法:

//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);
    }

IGroupNode、IStateNode等派生自ISceneNode。。。那么为什么我不能只用一个ISceneNode调用这个重载方法呢?是因为它不知道选择哪种方法?我如何在我的代码中解释这一点并解决它?

当您调用方法时,对象是ISceneNode,因为您没有定义PreVisitISceneNode,它将无法找到合适的方法

编译器将无法理解您已经为每个子类型定义了子类。一种解决方案是强制转换它,以检查您的对象是否实现了其中一个子接口,并在强制转换的对象上调用该方法

当然,这不是一个很好的解决方案,只是把它写在剩下的代码的中间。正如SLaks提到的,您应该使用dispatch,like,或者使用C4.0关键字dynamic,如图所示

下面是第二个链接的示例:

class Animal 
{ 
}

class Cat : Animal 
{ 
}

class Dog : Animal 
{ 
}
以下是专业:

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."); 
}
下面是如何在C 4.0中使用dynamic定义双重分派:

然后跑

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

    React(cat, dog); 
    React(dog, cat); 
}
C dynamic很好地做到了这一点:

PreVisit((dynamic)node);

在运行时使用C语义选择适当的方法。

这称为多重或动态分派。你需要访客模式。我有访客模式。介意进一步解释吗?这实际上是SearchVisitor类的实现,它在这些节点的树上执行搜索?PreVisitIGroupNodenode;如果将节点设置为动态类型变量,运行时将自动选择最佳匹配重载,或者在不匹配时引发异常:foreach dynamic node in group作为IGroupNodeB但由于实现都是相同的,我认为最好使用继承。只需声明一个名为PreVisitISceneNode的方法。如果需要,方法本身可以调用虚拟重载。@PMF节点类本身必须有一个虚拟方法才能从虚拟分派中受益。那会有用的,是的。但这意味着所有子类都必须遵守该协议,并且知道访问者是什么。我希望node类不知道访问节点的概念。好的,那么您当然可以使用模板化参数或使用扩展方法编写访问者方法。
PreVisit((dynamic)node);