简体   繁体   English

如何编译扩展方法?

[英]How are extension methods compiled?

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

The process is exactly the same as overload resolution: 该过程与重载决策完全相同:

Func(myObject);

The compiler checks all functions named "Func" and tries to match the static type of myObject to the parametrs (possibly using conversions, upcasting to base class). 编译器检查名为“Func”的所有函数,并尝试将myObject的静态类型与参数匹配(可能使用转换,向上转换为基类)。 If it succeeds, then calls the appropriate function. 如果成功,则调用适当的函数。

If you realize that you can call extensions methods "in a normal way", then it clears up: 如果您意识到可以“以正常方式”调用扩展方法,那么它会清除:

static class MyExtensions
{
    public static void MyFunc(this string arg)
    {
        // ...
    }
}

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

For the given type (here string), the compiler just looks for all static functions with "this" modifier on the first argument and tries to match the static type on the left of the . 对于给定的类型(此处为字符串),编译器只在第一个参数上查找所有带有“this”修饰符的静态函数,并尝试匹配左侧的静态类型。 (in this example "a") with the parameter type in the function. (在此示例中为“a”),函数中包含参数类型。

Instance methods of a class have a hidden argument. 类的实例方法具有隐藏参数。 An example: 一个例子:

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

actually looks like this when the JIT compiler is done with it, converted back to C# syntax: 当JIT编译器完成它时,实际上看起来像这样,转换回C#语法:

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

That hidden argument is the reason that you can use this in an instance method. 隐藏的参数是您可以在实例方法中使用的原因。 The JIT compiler figures out the argument to pass from the object reference you provide to call the Foo method. JIT编译器计算出从您提供的对象引用传递的参数,以调用Foo方法。

As you can tell, it is now a very short hop to an extension method. 正如您所知,它现在是一个非常短暂的扩展方法。

The compiler first looks in the base class for a function matching the signature of the function. 编译器首先在基类中查找与函数签名匹配的函数。 If it can't find it than it looks for an extension. 如果它找不到它而不是寻找扩展名。 If an extension has the same signature as a base class method than the base class method is called instead. 如果扩展名与基类方法具有相同的签名,则调用基类方法。

This might help: Extension Methods 这可能会有所帮助: 扩展方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM