多态性和显式铸造

时间:2015-12-30 12:38:50

标签: c# casting polymorphism

我有以下架构(类比很糟糕,但W / E )。

enter image description here

program和其他逻辑类中,我有很多方法使用特定类型的手指(MonkeyFinger)。这意味着我必须明确地转换所有那些testMethods。

是否有任何设计模式/解决方案可以避免显式转换?

编辑代码:

Monkey govi = new Monkey(...)
Program test = new Program()
test.testFinger1((MonkeyFinger) govi.GetHand.getFinger)

...

3 个答案:

答案 0 :(得分:5)

您可以尝试这样的事情:

public class Animal<TFingerType> where TFingerType : IFinger
{
    Hand<TFingerType> GetHand() 
    {
        //... Do something
    }
}

public class Monkey : Animal<MonkeyFinger> { }
public class Hand<TFingerType> where TFingerType : IFinger
{

}
public interface IFinger
{

}
public class MonkeyFinger : IFinger {
}

至少在你给出的例子中,Monkey返回包含HumanFinger s的牌是没有意义的。手本身实际上是由它具有什么类型的手指来定义的。

然后您的代码变为:

Monkey govi = new Monkey(...)
Program test = new Program()
test.testFinger1(govi.GetHand.getFinger() /* getFinger here returns a MonkeyFinger */)

请注意,手指仍为IFingers,并且可以在该上下文中使用,但此方法还提供具体类型的手指。

答案 1 :(得分:0)

我认为最好创建一个方法来为您进行检查。是的,如果你想测试一些假设(比如猴子只有猴子的手指),那么铸造是必要的。

类似的东西:

public static T TestAndConvert<T>(object o)
{
    Assert.IsInstanceOfType(o, typeof(T));

    return (T)o;
}

首先检查类型是否正确,然后返回一个类型化实例。这样您就可以确定类型是否正确并且您已经进行了适当的测试。

在测试呼叫中使用它:

testFinger1(TestAndConvert<MonkeyFinger>(finger));

(从您的图表中我不确定您是否使用自动化测试框架,如Visual Studio中的单元测试,我建议这样做)

答案 2 :(得分:0)

是否真的需要将具体指针传递给测试方法?当您使用接口时,您将定义一个合同,每个实现都应遵循该合同。您可以使用方法覆盖扩展子类中的父行为(或替换它但它与Liskov substitution principle不对应),但是您只测试合同然后为什么需要在测试方法中传递使用IFFinger的MonkeyFinger?