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.