首页 > 解决方案 > C#:为什么我不能在扩展方法中使用动态参数?

问题描述

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

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);不会导致任何错误。

标签: c#extension-methods

解决方案


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

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

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


推荐阅读