C#中静态方法的多态性和重载。

时间:2011-07-28 12:13:31

标签: c# polymorphism overloading

我一直在尝试根据函数Item <的输入参数(我称之为上下文)生成一个应该返回公共接口的另一个对象(例如getItem(A context))的工厂/ p>

现在,假设我定义了一种新的上下文:B,它继承自A

我想返回一个不同的项目,具体取决于传递给工厂的对象是B类还是A

我试着做如下(重载方法):

class Factory
{
   static Item getItem(A context) {...}
   static Item getItem(B context) {...}
}

如果我这样做,这样可以正常工作:

B bContext=new B();
Item it=Factory.getItem(bContext);

但是,如果我将对象转换为对象A

A bContext=(A) new B();
Item it=Factory.getItem(bContext);

调用第一个工厂方法。

我认为即使在演员之后,多态也会确保第二种方法的执行,我想知道我是否错过了什么?

我知道我可以继续使用单个方法并使用is运算符来检查变量的类型,但我认为上面提到的解决方案更优雅。

2 个答案:

答案 0 :(得分:10)

根据参数的编译时类型,在编译时(除了在C#4中使用动态类型)决定重载 - 在最后一个片段中,编译时类型为参数为A,因此它调用Factory.getItem(A)

只有虚方法调用是多态的(使用覆盖),其中目标对象的实际执行时类型决定调用哪个实现。如果AB有一个虚拟方法(在B中重写)可以被Factory.getItem调用以处理差异,那就太有意义了......否则你会遇到动态类型或类似is的问题。

答案 1 :(得分:1)

你无法实现你现在假装的方式。

一种选择是在工厂方法中使用一些可以区分参数类型的逻辑。笨重,不漂亮,但它有效:

class Factory
{
    static Item getItem(ContextA context)
    {
         if (context is ContextB) {...}
         else {...}
    }
}

另一个选择是使上下文对象负责创建对象。例如:

public class ContextA
{
     ....
     internal virtual Item CreateItem() { //specific creation logic for ContextA }
}

public class ContextB: ContextA
{
     ....
     internal override Item CreateItem() { //specific creation logic for ContextB }
}

现在你可以这样做:

class Factory
{
    static Item getItem(ContextA context)
    {
         return context.CreateItem();
    }
}

否,如果您执行以下操作:

 ContextA context = new ContextB();
 Item item = Factory.getItem(context)

ContextB.CreateItem()将被调用。