C#编译器如何实现扩展方法?
答案 0 :(得分: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”),函数中包含参数类型。
答案 1 :(得分:3)
类的实例方法有一个隐藏参数。一个例子:
class Example {
public void Foo(int arg) {}
}
当JIT编译器完成后,实际上看起来像这样,转换回C#语法:
static void Foo(Example this, int arg) {}
隐藏的参数是您可以在实例方法中使用 this 的原因。 JIT编译器计算出从您提供的对象引用传递的参数,以调用Foo方法。
正如您所知,它现在是扩展方法的非常短跃点。
答案 2 :(得分:0)
编译器首先在基类中查找与函数签名匹配的函数。如果它找不到它而不是寻找扩展名。如果扩展名与基类方法具有相同的签名,则调用基类方法。
这可能会有所帮助: Extension Methods