我试图准确地理解单次和多次调度是什么。
我刚读到这个:
http ://en.wikipedia.org/wiki/Multiple_dispatch
从这个定义来看,在我看来,C# 和 VB.Net 是多调度的,即使在编译时选择调用哪个重载也是如此。
我在这里是正确的,还是我错过了什么?谢谢!
我试图准确地理解单次和多次调度是什么。
我刚读到这个:
http ://en.wikipedia.org/wiki/Multiple_dispatch
从这个定义来看,在我看来,C# 和 VB.Net 是多调度的,即使在编译时选择调用哪个重载也是如此。
我在这里是正确的,还是我错过了什么?谢谢!
好的,我理解函数重载与多次调度的细微差别。
基本上,区别在于调用哪个方法是在运行时还是编译时选择的。现在,我知道每个人都这么说,但没有一个明确的例子,这听起来很明显,因为 C# 是静态类型的,而多调度语言(至少对我来说显然)似乎是动态类型的。到现在为止,就这个定义而言,多重调度和函数重载对我来说听起来完全一样。
真正不同的情况是,当您有 2 个在参数类型上不同的方法重载时,但是这 2 个类型是多态的,并且您使用声明为更高类型的引用进行调用,该引用的对象为较低的类型...(如果有人能想到更好的表达方式,请随时编辑此答案)
例子:
int CaptureSpaceShip(IRebelAllianceShip ship) {}
int CaptureSpaceShip(XWing ship) {}
void Main() {
IRebelAllianceShip theShip = new XWing();
CaptureSpaceShip(theShip);
}
XWing 显然实现了 IRebelAllianceShip。在这种情况下,将调用第一个方法,而如果 C# 实现了多次调度,则将调用第二个方法。
对文档重新哈希感到抱歉...在我看来,这似乎是解释这种差异的最清晰方法,而不仅仅是阅读每个调度方法的定义。
更正式的解释: http ://en.wikipedia.org/wiki/Double_dispatch#Double_dispatch_is_more_than_function_overloading
对于那些使用搜索引擎找到这篇文章的人,C# 4.0 引入了动态关键字。代码如下所示。
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);
}
这是因为“动态”强制转换,它告诉 C# 编译器,而不是仅仅调用 ReactSpecialization(Animal, Animal),动态检查每个参数的类型并在运行时选择要调用的方法重载。
为了证明它确实有效:
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# 4.0(动态)是“多调度”语言。
我还认为 Java、C#(4.0 之前的版本)、C++ 等语言是单调度的。
C# 不支持多分派。访问者设计模式模拟了可以描述为多次分派的东西,尽管访问者模式主要关注将算法与层次结构分离。
根据引用的 Wikipedia 文章,根据定义,多重分派是基于所涉及对象的运行时类型,因此 C# 和 VB.net不使用它,因为正如您所说,在编译时做出决定.
GoF 访问者模式是如何进行双重调度的示例。Scott Meyers “更有效的 C++” 向您展示了如何在 C++ 中执行此操作。这是 Dobbs 博士的链接,讨论了如何在 Java 和 C++ 中进行双重调度。
我明白这是一个老问题..
在 .Net 4.0 中,您可以dynamic
为多种方法使用关键字...请看下面的示例.Net 4.0 重构现有“if”条件和“is”运算符的优化代码