扩展方法是如何编译的?

9

C#编译器如何实现扩展方法?

3个回答

6

这个过程与重载解析完全相同:

Func(myObject);

编译器检查所有名为“Func”的函数,并尝试将myObject的静态类型与参数匹配(可能使用转换,向基类进行向上转型)。如果成功,则调用相应的函数。
如果您意识到可以以“正常方式”调用扩展方法,则会更加清晰:
static class MyExtensions
{
    public static void MyFunc(this string arg)
    {
        // ...
    }
}

string a = "aa";
MyExtensions.MyFunc(a); // OK
a.MyFunc();             // same as above, but nicer

对于给定的类型(这里是字符串),编译器只会查找所有第一个参数带有“this”修饰符的静态函数,并尝试将左侧的静态类型(在本例中为“a”)与函数中的参数类型匹配。


3

类的实例方法有一个隐藏参数。例如:

class Example {
  public void Foo(int arg) {}
}

在JIT编译器完成后,实际上它的样子是这样的,转换回C#语法:

static void Foo(Example this, int arg) {}

那个隐藏的参数就是你可以在实例方法中使用this的原因。JIT编译器会从你提供的对象引用中找到要传递的参数来调用Foo方法。
可以看出,现在很容易转化为扩展方法了。

0
编译器首先在基类中查找与函数签名匹配的函数。如果找不到,则会查找扩展方法。如果扩展方法与基类方法具有相同的签名,则调用基类方法。
这可能会有所帮助: 扩展方法

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接