"动态"类型的表达式在运行时的行为是否与同一运行类型时间的非动态表达式相同?

Tim*_*mwi 12 c# dynamic

请考虑以下示例程序:

using System;
public delegate string MyDelegateType(int integer);

partial class Program
{
    static string MyMethod(int integer) { return integer.ToString(); }

    static void Main()
    {
        Func<int, string> func = MyMethod;

        // Scenario 1: works
        var newDelegate1 = new MyDelegateType(func);
        newDelegate1(47);

        // Scenario 2: doesn’t work
        dynamic dyn = func;
        var newDelegate2 = new MyDelegateType(dyn);
        newDelegate2(47);
    }
}
Run Code Online (Sandbox Code Playgroud)

第一个按预期工作 - 转换MyDelegateType成功.但是,第二个会抛出一条RuntimeBinderException错误消息:

无法将类型'System.Func <int,string>'隐式转换为'MyDelegateType'

C#规范中是否存在允许此行为的任何内容,或者这是Microsoft C#编译器中的错误?

Eri*_*ert 16

好抓Timwi.

我们对动态方法组的支持很弱.例如,考虑这个更简单的情况:

class C
{
  public void M() {}
}

class P
{
    static void Main()
    {
        dynamic d = new C();
        C c = new C();
        Action a1 = c.M; // works
        Action a2 = d.M; // fails at runtime
Run Code Online (Sandbox Code Playgroud)

它d.M被动态运行时解释为属性get(或字段访问),当它作为方法组解析时,它在运行时失败.

同样的事情发生在你的情况下,它只是有点模糊.当你说MyDelegate x = new MyDelegate(someOtherDelegate);编译器对待它时就像你说的那样MyDelegate x = someOtherDelegate.Invoke;.动态运行时块不知道要进行那种转换,即使它确实如此,它也无法处理解析.Invoke作为表达式部分结果的方法组.

C#规范中是否存在允许此行为的任何内容,或者这是Microsoft C#编译器中的错误?

规范没有提到这应该是运行时错误,并且暗示它应该在运行时正确处理; 显然,实施不会这样做.虽然这是实施的一个缺点,但我不会称之为"错误",因为我们故意制造了你发现的行为.我们没有资源让这些表达式完全正确,所以我们将它们留作错误.如果我们在动态运行时中获得表示方法组的好方法,我们可能会实现它.

类似地,动态代码中没有办法表示"这个动态的东西是一个lambda表达式,其中参数的类型将在运行时确定".如果我们有一个很好的方式来代表未来的人,我们可能会做这项工作.

山姆在2008年谈到了这个问题; 看他的文章:

http://blogs.msdn.com/b/samng/archive/2008/11/02/dynamic-in-c-ii-basics.aspx