.NET 4.0中新的"动态"变量类型是否解决了CLR中的单/多方法调度问题?

Bub*_*a88 7 .net c# multiple-dispatch dynamic-typing c#-4.0

单个调度的问题对于使用Java和C#等静态类型语言进行编码的人来说大多是熟悉的.基本思路是:

虽然运行时多态性允许我们根据类型(运行时类型)调度到正确的方法调用receiver,例如:

IAnimal mything = new Cat();
mything.chop();
Run Code Online (Sandbox Code Playgroud)

方法调用将根据运行时类型执行mything,即Cat.这是单一调度功能(存在于Java/C#中).

现在,如果您不仅需要调度接收器的运行时类型,还需要调度(多个)参数的类型,那么您将面临一个小问题:

public class MyAcceptor {  
    public void accept (IVisitor vst) {...}   
    public void accept (EnhancedConcreteVisitor vst) {...}  
}
Run Code Online (Sandbox Code Playgroud)

第二种方法永远不会被调用,因为在我们的"消费者"代码中,我们倾向于通过常见的超类型或接口来处理不同类型的对象(在我的示例中为访问者).

这就是我问的原因 - 因为动态类型允许多重调度多态,C#4.0有动态关键字;)

Jon*_*eet 12

是的,动态类型允许多次调度 - 不,您不必创建自己的动态对象来执行此操作.

假设我们想要实现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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我不是说这是个好主意,但这就是它的工作原理:)

请注意,您需要注意不要引入最终可能会对某些类型进行模糊调用的情况.这不是使用参数类的问题,但考虑到单个类可以实现多个接口.