.NET 4.0中新的“动态”变量类型是否解决了CLR中的单/多方法调度问题?
单个调度的问题对于使用Java和C#等静态类型语言进行编码的人来说大多是熟悉的。 基本思路是:
运行时多态性允许我们根据receiver
的类型(运行时类型)调度到正确的方法调用,例如:
IAnimal mything = new Cat(); mything.chop();
方法调用将根据mything
的运行时类型mything
,即Cat
。 这是单一调度function(存在于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(this IEnumerable source) { dynamic d = source; return CountImpl(d); } private static int CountImpl (ICollection collection) { return collection.Count; } private static int CountImpl(ICollection collection) { return collection.Count; } private static int CountImpl (string text) { return text.Length; } private static int CountImpl (IEnumerable source) { // Fallback int count = 0; foreach (T t in source) { count++; } return count; } }
我不是说这是个好主意,但这就是它的工作原理:)
请注意,您需要注意不要引入最终可能会对某些类型进行模糊调用的情况。 这不是使用参数类的问题,但考虑到单个类可以实现多个接口。
是的,您可以创建任意复杂调度的DLR类型。 查看http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.aspx