C#是单一分派语言还是多分派语言?

C#是单一分派语言还是多分派语言?,c#,programming-languages,multiple-dispatch,single-dispatch,C#,Programming Languages,Multiple Dispatch,Single Dispatch,我想弄清楚什么是单次和多次调度 我刚刚读到: 从这个定义来看,在我看来,C#和VB.Net是多分派的,即使选择调用哪个重载是在编译时进行的 我是对的,还是我遗漏了什么? 谢谢 C#是单次发送,但有些博客文章的标题看起来像是在模仿多种方法。如果我能下载其中一篇文章,我将在这里更新我的答案。GoF访问者模式就是如何进行双重分派的一个示例。Scott Meyers“更有效的C++”向你展示了如何在C++中完成它。这里有一个多布斯博士的文章,讨论如何在java和C++中进行双调度。 < P> C不支持

我想弄清楚什么是单次和多次调度

我刚刚读到:

从这个定义来看,在我看来,C#和VB.Net是多分派的,即使选择调用哪个重载是在编译时进行的

我是对的,还是我遗漏了什么?
谢谢

C#是单次发送,但有些博客文章的标题看起来像是在模仿多种方法。如果我能下载其中一篇文章,我将在这里更新我的答案。

GoF访问者模式就是如何进行双重分派的一个示例。Scott Meyers“更有效的C++”向你展示了如何在C++中完成它。这里有一个多布斯博士的文章,讨论如何在java和C++中进行双调度。

< P> C不支持多调度。Visitor设计模式模拟可以被描述为多重分派的东西,尽管Visitor模式主要关注将算法从层次结构中分离出来。

根据定义,多重分派基于所涉及对象的运行时类型,因此C#和VB.net不使用它,正如您所说,因为决策是在编译时做出的。

好的,我理解了函数重载与多次分派之间的细微差别

基本上,区别在于是在运行时还是在编译时选择调用哪个方法。现在,我知道每个人都这么说了,但没有一个明确的例子,这听起来很明显,因为C#是静态类型的,而多个调度语言(至少在我看来)似乎是动态类型的。到目前为止,对于这个定义,多重分派和函数重载对我来说听起来完全一样

这种情况下,一个方法有两个重载,它们在参数类型上不同,但这两个类型是多态的,并且调用时引用声明为较高的类型,该类型具有较低类型的对象。。。 (如果有人能想出更好的表达方式,请随意编辑此答案)

例如:

int CaptureSpaceShip(IRebelAllianceShip ship) {}
int CaptureSpaceShip(XWing ship) {}

void Main() { 
  IRebelAllianceShip theShip = new XWing();
  CaptureSpaceShip(theShip);
}
XWing显然实现了iRebeallianceship。 在这种情况下,将调用第一个方法,而如果C#实现了多个分派,则将调用第二个方法

关于医生复职的事很抱歉。。。在我看来,这似乎是解释这种差异的最清晰的方式,而不仅仅是阅读每个分派方法的定义

要获得更正式的解释:

对于那些使用搜索引擎查找本文的人,C#4.0引入了关键字。代码如下所示

int CaptureSpaceShip(IRebelAllianceShip ship) {}
int CaptureSpaceShip(XWing ship) {}

void Main() {   
    IRebelAllianceShip theShip = new XWing();  
    CaptureSpaceShip((dynamic)theShip);
}

我知道这是个老问题


在.NET4.0中,您可以对多种方法使用
dynamic
关键字。。。请看下面的示例

也许有人会对使用动态关键字()

我们可以创建同一方法的多个重载,根据其参数类型的不同组合进行专门化:

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); 
}
这是因为“as dynamic”cast告诉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)之前的C++语言是单调度的。

这是一个很重要的例子。谢谢!我需要一个这样的例子。@Daniel Magliola,请注意,在C#4.0中,通过使用动态“多个调度语言似乎是动态键入的”,动态调度现在成为可能。在阅读之后,这就是我如何回答这个问题的,我认为事实恰恰相反(参见他说的“将类型放入Perl 6的主要原因不是强类型,而是多个分派”)。如果你要根据参数类型决定调用什么方法,你可能需要有一个显式类型的方法定义,这是动态类型语言通常没有的(至少是我见过的语言)。@David Mulfrod的答案(新的动态关键字)应该是正确的答案-即,如果您愿意,那么您可以让CLR执行动态分派(我猜JVM的invoke dynamic类似,但它不适用于Java)+1。C#4.0支持多分派。下面的版本称为动态调度。多重分派只是能够进行动态参数类型解析的副产品。
Cat runs away from dog.
Cat chases mouse.
Dog chases cat.
Dog is not interested in Mouse.