C#:为什么不能在扩展方法中使用动态参数?

时间:2018-09-30 07:19:24

标签: c# extension-methods

为什么不能在扩展方法中使用动态参数,如以下代码所示:

public static class Extension
{
    public static void ExtMethod(this Program pg, object asdf) {
        new Program();
    }
}

public class Program
{
    static void Main(string[] args)
    {
        dynamic d = new ExpandoObject();
        d.test = "test";
        new Program().ExtMethod(d.test);
        Extension.ExtMethod(new Program(), d.test);
    }
}    

new Program().ExtMethod(d.test);抛出编译时错误。

但是Extension.ExtMethod(new Program(), d.test);不会引起任何错误。

2 个答案:

答案 0 :(得分:5)

这是设计使然,也是规范的一部分。根据ECMA C#5标准,第12.7.6.3节:

  

在一种形式的方法调用(第1.2.6.6.2节)中,如果调用的正常处理未找到适用的方法,则尝试将构造作为扩展方法调用进行处理。 如果expr或任何arg具有动态编译时类型,则扩展方法将不适用。

造成这种情况的根本原因是,动态绑定旨在提供与编译时的绑定相同的结果……但是对于扩展方法,这意味着在执行时保留所有using指令。那可能是可能,但是我怀疑这在调用性能方面会非常昂贵,因此C#设计团队决定不采用这种方式。

答案 1 :(得分:0)

您需要将d.test强制转换为一个对象,换句话说,写为;

new Program().ExtMethod((object)d.test);