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

Posted

技术标签:

【中文标题】C# 中的静态方法的多态性和重载。【英文标题】:Polymorphism and overloading with static methods in C#. 【发布时间】:2011-10-15 02:01:39 【问题描述】:

我一直在尝试根据函数getItem(A context)的输入参数(我称之为上下文)生成一个工厂,它应该返回一个公共接口的不同对象(比如Item

现在,假设我定义了一种新的上下文类型: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 运算符来检查变量的类型,但我认为我上面介绍的解决方案更优雅一些。

【问题讨论】:

【参考方案1】:

重载是在编译时根据参数的编译时类型决定的(除了在 C# 4 中使用动态类型) - 在你最后的 sn-p 中,编译时参数的类型是A,所以它调用Factory.getItem(A)

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

【讨论】:

【参考方案2】:

你无法实现你现在所设置的方式。

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

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() 将被调用。

【讨论】:

以上是关于C# 中的静态方法的多态性和重载。的主要内容,如果未能解决你的问题,请参考以下文章

2017-4-16 多态 构造函数 方法重载 静态方法和静态成员

详细说明:方法重载是静态/编译时绑定,但不是多态性。将静态绑定与多态性相关联是不是正确?

☀️ 学会编程入门必备 C# 最基础知识介绍——方法封装继承多态

C++JavaC# 多态知识总结

C++JavaC# 多态知识总结

C++JavaC# 多态知识总结