扩展方法是如何在内部实现的?也就是说,当编译器看到扩展方法的声明时会发生什么,以及当调用扩展方法时运行时会发生什么。
是否涉及反射?或者当您有一个扩展方法时,它的代码是否注入目标类类型元数据中,并附加一些额外的标志来说明这是一个扩展方法,然后CLR知道如何处理它?
总之,在幕后会发生什么?
是否涉及反射?或者当您有一个扩展方法时,它的代码是否注入目标类类型元数据中,并附加一些额外的标志来说明这是一个扩展方法,然后CLR知道如何处理它?
总之,在幕后会发生什么?
正如其他同事已经说过的,它只是一个静态方法。 从编译器的角度来看,我们可以说CLR甚至对扩展方法一无所知。 你可以尝试检查IL代码。。
这里有一个例子
static class ExtendedString
{
public static String TestMethod(this String str, String someParam)
{
return someParam;
}
}
static void Main(string[] args)
{
String str = String.Empty;
Console.WriteLine(str.TestMethod("Hello World!!"));
........
}
这里是IL代码。
IL_0001: ldsfld string [mscorlib]System.String::Empty
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldstr "Hello World!!"
IL_000d: call string StringPooling.ExtendedString::TestMethod(string,
string)
IL_0012: call void [mscorlib]System.Console::WriteLine(string)
IL_0017: nop
正如您所看到的,这只是一个静态方法的调用。 该方法没有添加到类中,但编译器使其看起来像是添加了。 而在反射层面,您唯一能看到的区别是添加了CompilerServices.ExtensionAttribute。
我认为反射
与扩展方法无关。扩展方法的处理方式与在助手类
中编写静态助手函数
相同,唯一的区别是编译器替你完成这项工作。
为了澄清上面的答案... 扩展方法是静态函数。.NET 3.5中的附加功能使它们被解释为类型中的新方法。
是的,扩展方法只是静态方法。它们与它们所谓“扩展”的类没有额外的特权。然而,编译器确实使用ExtensionAttribute标记“扩展”静态方法。您可以在IL中看到这一点。这使得编译器将其特殊处理,因此您实际上无法将其作为常规静态方法调用。例如,以下代码将无法编译:
var test = new [] { "Goodbye", "Cruel", "World" };
var result = IEnumerable<string>.Where<string>(test, s => s.Length > 5);
尽管这是在幕后发生的事情。
但正如LukeH在下面指出的那样,您可以在实际定义它的类上调用它...我太傻了。
扩展方法只是静态方法。唯一的区别在于像Visual Studio编辑器这样的工具会为自动完成(智能感知)功能弹出它们。您可以在此处找到详细说明:C#扩展方法:语法糖还是有用的工具?
扩展方法与static
方法非常相似,唯一的区别在于它具有一个属性CompilerServices.ExtensionAttribute
,这有助于将其识别为扩展方法。
您可以阅读此内容
var result = Enumerable.Where<string>(test, s => s.Length > 5);
- LukeH