单次调度的问题对于使用 Java 和 C# 等静态类型语言进行编码的人来说最为熟悉。基本思想是:
而运行时多态性允许我们根据类型(运行时类型)分派到正确的方法调用receiver
, 例如:
IAnimal mything = new Cat();
mything.chop();
方法调用将根据运行时类型进行mything
,即Cat
。
这是单一调度功能(Java/C# 中存在)。
现在,如果您不仅需要在接收器的运行时类型上进行分派,而且还需要在(多个)参数的类型上进行分派,那么您将面临一个小问题:
public class MyAcceptor {
public void accept (IVisitor vst) {...}
public void accept (EnhancedConcreteVisitor vst) {...}
}
第二种方法永远不会被调用,因为在我们的“消费者”代码中,我们只是倾向于通过公共超类型或接口来处理不同类型的对象(我的示例中的访问者)。
这就是我问的原因 - 因为动态类型允许多重分派多态性,并且 C# 4.0 有该动态关键字;)
是的,动态类型允许多次分派 - 不,您不必创建自己的动态对象来执行此操作。
假设我们想要实现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;
}
}
我并不是说这是一个好主意,但这就是它的工作原理:)
请注意,您需要小心,不要引入可能最终对某些类型进行不明确调用的情况。使用类作为参数这不会成为问题,但请考虑单个类可以实现多个接口。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)