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)
。
只有虚方法调用是多态的(使用覆盖),其中目标对象的实际执行时类型来决定调用哪个实现。如果A
和B
有一个可以由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 多态 构造函数 方法重载 静态方法和静态成员
详细说明:方法重载是静态/编译时绑定,但不是多态性。将静态绑定与多态性相关联是不是正确?