使用静态类型语言(如 Java 和 C#)进行编码的人最熟悉单一分派(dispatch)的问题。基本思想是:
而运行时多态允许我们根据receiver
的类型(runtime type)调度到正确的方法调用,例如:
IAnimal mything = new Cat();
mything.chop();
方法调用将根据mything
的运行时类型执行,即Cat
。
这是单一分派(dispatch)能力(在 Java/C# 中存在)。
现在,如果您不仅需要分派(dispatch)接收器的运行时类型,还需要分派(dispatch)(多个)参数的类型,您会遇到一个小问题:
public class MyAcceptor {
public void accept (IVisitor vst) {...}
public void accept (EnhancedConcreteVisitor vst) {...}
}
第二种方法永远不会被调用,因为在我们的“消费者”代码中,我们只是倾向于通过它们的公共(public)父类(super class)型或接口(interface)来处理不同类型的对象(在我的例子中是访问者)。
这就是我问的原因 - 因为动态类型允许多重分派(dispatch)多态性并且 C# 4.0 有那个动态关键字 ;)
最佳答案
是的,动态类型允许多次分派(dispatch) - 不,您不必创建自己的动态对象来做到这一点。
假设我们想自己实现Enumerable.Count()
,我们不想在代码中加载“if (source is IList)
”测试.我们可以这样写:
public static class Enumerable
{
public static int Count<T>(this IEnumerable<T> source)
{
dynamic d = source;
return CountImpl(d);
}
private static int CountImpl<T>(ICollection<T> collection)
{
return collection.Count;
}
private static int CountImpl(ICollection collection)
{
return collection.Count;
}
private static int CountImpl<T>(string text)
{
return text.Length;
}
private static int CountImpl<T>(IEnumerable<T> source)
{
// Fallback
int count = 0;
foreach (T t in source)
{
count++;
}
return count;
}
}
我并不是说这是个好主意,但这就是它的工作方式:)
请注意,您需要注意不要引入可能导致对某些类型的模棱两可的调用的情况。使用类作为参数这不是问题,但考虑到单个类可以实现多个接口(interface)。
关于c# - .NET 4.0 中新的 'dynamic' 变量类型是否解决了 CLR 中的单/多方法调度问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2752523/