我正在尝试准确理解"单分派"和"多分派"是什么意思。
我刚刚阅读了这篇文章:
http://en.wikipedia.org/wiki/Multiple_dispatch
从那里的定义来看,似乎C#和VB.Net属于多分派,尽管选择调用哪个重载是在编译时确定的。
我这样理解是否正确?还是我漏掉了什么? 谢谢!
我正在尝试准确理解"单分派"和"多分派"是什么意思。
我刚刚阅读了这篇文章:
http://en.wikipedia.org/wiki/Multiple_dispatch
从那里的定义来看,似乎C#和VB.Net属于多分派,尽管选择调用哪个重载是在编译时确定的。
我这样理解是否正确?还是我漏掉了什么? 谢谢!
好的,我理解函数重载与多分派之间微妙的区别。
基本上,区别在于选择调用哪个方法是在运行时还是编译时决定的。现在,我知道每个人都说过这个,但是没有明确的例子,这听起来非常显然,因为C#是静态类型语言,而多分派语言(至少对我来说)似乎是动态类型。到目前为止,仅凭那个定义,多分派和函数重载对我来说完全相同。
这种情况真正产生影响的地方是当您:
CaptureSpaceShip(IRebelAllianceShip ship)
和 CaptureSpaceShip(Xwing ship)
)IRebelAllianceShip
和 CaptureSpaceShip
) 是多态的,并且完整示例:
int CaptureSpaceShip(IRebelAllianceShip ship) {}
int CaptureSpaceShip(XWing ship) {}
void Main() {
IRebelAllianceShip theShip = new XWing();
CaptureSpaceShip(theShip);
}
对于通过搜索引擎找到这篇文章的读者,C# 4.0 引入了 dynamic 关键字。代码如下所示。
int CaptureSpaceShip(IRebelAllianceShip ship) {}
int CaptureSpaceShip(XWing ship) {}
void Main() {
IRebelAllianceShip theShip = new XWing();
CaptureSpaceShip((dynamic)theShip);
}
C#是单分派语言,但有些博客文章的标题看起来像是在模拟多态方法。如果我能加载其中一篇文章,我会在这里更新我的答案。
也许有些人会对使用动态关键字的多重调度的好的C#实例感兴趣(MSDN博客)
class Animal
{
}
class Cat : Animal
{
}
class Dog : Animal
{
}
class Mouse : 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(Cat me, Mouse other)
{
Console.WriteLine("Cat chases mouse.");
}
void ReactSpecialization(Dog me, Cat other)
{
Console.WriteLine("Dog chases cat.");
}
现在是有趣的部分:
void React(Animal me, Animal other)
{
ReactSpecialization(me as dynamic, other as dynamic);
}
void Test()
{
Animal cat = new Cat();
Animal dog = new Dog();
Animal mouse = new Mouse();
React(cat, dog);
React(cat, mouse);
React(dog, cat);
React(dog, mouse);
}
输出:
Cat runs away from dog.
Cat chases mouse.
Dog chases cat.
Dog is not interested in Mouse.
C#不支持多重分派。访问者设计模式模拟了可以描述为多重分派的东西,尽管访问者模式主要专注于将算法与层次结构分离。
我知道这是一个老问题...
在 .Net 4.0 中,您可以使用 dynamic
关键字来进行多方法操作... 请参考以下示例 .Net 4.0 优化代码以重构现有的 "if" 条件和 "is" 运算符
CaptureSpaceShip((IRebelAllianceShip)theShip)
调用IRebelAllianceShip
重载(与theShip
的值无关),但在这里强制转换是不必要的,因为变量已经被静态声明为IRebelAllianceShip
。CaptureSpaceShip((XWing)theShip)
调用 XWing 重载(或者如果theShip
不是XWing
则崩溃)。在 C# 4.0+ 中,CaptureSpaceShip((dynamic)theShip)
调用最具体的适用重载(或者如果两个适用重载同样具体,则崩溃)。 - Bjartur Thorlacius