如何向下转换为重载方法

时间:2013-11-01 18:27:04

标签: c# relationship downcast

我的代码中有一点问题,我觉得很有意思:

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调用这个重载方法?是因为它不知道选择哪种方法?如何在我的代码中解释这一点并解决它?

2 个答案:

答案 0 :(得分:2)

当你调用你的方法时,对象是ISceneNode,因为你没有定义PreVisit(ISceneNode),它将无法找到合适的方法。

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

当然,在其余的代码中间写这个并不是一个很好的解决方案。正如SLaks所提到的那样,您应该使用here之类的调度,或使用C#4.0关键字dynamic,如图所示here

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

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."); 
}

现在,您可以使用dynamic

在C#4.0中定义双重调度
void React(Animal me, Animal other) 
{ 
    ReactSpecialization(me as dynamic, other as dynamic); 
}

然后运行

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

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

答案 1 :(得分:1)

C#dynamic做得很好:

PreVisit((dynamic)node);

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