这是动态的错误吗?

con*_*tor 12 c# dynamic compiler-bug

dynamic泛型类上实现动态分派,并且泛型类型参数是另一个类上的私有内部类时,运行时绑定程序会引发异常.

例如:

using System;

public abstract class Dispatcher<T> {
    public T Call(object foo) { return CallDispatch((dynamic)foo); }

    protected abstract T CallDispatch(int foo);
    protected abstract T CallDispatch(string foo);
}

public class Program {
    public static void Main() {
        TypeFinder d = new TypeFinder();

        Console.WriteLine(d.Call(0));
        Console.WriteLine(d.Call(""));
    }

    private class TypeFinder : Dispatcher<CallType> {
        protected override CallType CallDispatch(int foo) {
            return CallType.Int;
        }

        protected override CallType CallDispatch(string foo) {
            return CallType.String;
        }
    }

    private enum CallType { Int, String }
}
Run Code Online (Sandbox Code Playgroud)

在这里,RuntimeBinderException将抛出一条消息

由于其保护级别,'Dispatcher.CallDispatch(int)'无法访问

究其原因,交通不便的是,该类型参数T是私人CallTypeDispatcher<T>不能访问.因此,CallDispatch必须是不可访问的 - 但事实并非如此,因为它可以访问T.

这是一个错误dynamic,或者这不应该被支持?

Ben*_*igt 4

这是一个错误。如果您可以静态地进行调用(并且您可以),那么您应该能够动态地进行调用。

具体来说,以下代码有效:

using System;

public abstract class Dispatcher<T> {
    public T Call(object foo)
    {
        return CallDispatch(((object)(dynamic)foo).ToString());
    }

    protected abstract T CallDispatch(int foo);
    protected abstract T CallDispatch(string foo);
}

public class Program {
    public static void Main() {
        TypeFinder d = new TypeFinder();

        Console.WriteLine(d.Call(0));
        Console.WriteLine(d.Call(""));
    }

    private class TypeFinder : Dispatcher<CallType> {
        protected override CallType CallDispatch(int foo) {
            return CallType.Int;
        }

        protected override CallType CallDispatch(string foo) {
            return CallType.String;
        }
    }

    private enum CallType { Int, String }
}
Run Code Online (Sandbox Code Playgroud)

请注意,我曾经ToString()使静态类型为已知,C# 编译器和 CLR 允许此上下文访问私有类型CallType,因此 DLR 也应该允许它。

  • 并非每个静态有效的调用都是动态有效的。例如:`IList&lt;int&gt; x = new int[10]; Console.WriteLine(x.Count);` 工作正常 - 但如果您使用 `dynamic x = new int[10]; Console.WriteLine(x.Count);` 不会,因为 `Count` 是显式实现的。 (2认同)