C# 扩展方法是CLR的语言特性还是CLR的语言特性?
C#3为我们带来了扩展方法 但是,其他语言(如VB.NET)也通过在必须在VB.NET模块中声明的方法之上指定属性声明来实现扩展方法 此外,还可以在C++/CLI中使用扩展方法 所以,我想知道扩展方法是语言特性还是CLR内置的特性C# 扩展方法是CLR的语言特性还是CLR的语言特性?,c#,.net,clr,C#,.net,Clr,C#3为我们带来了扩展方法 但是,其他语言(如VB.NET)也通过在必须在VB.NET模块中声明的方法之上指定属性声明来实现扩展方法 此外,还可以在C++/CLI中使用扩展方法 所以,我想知道扩展方法是语言特性还是CLR内置的特性 我猜这是一个编译器技巧,因为您甚至可以将它们作为声明类型的纯静态方法调用,因此必须是特定于语言的特性(微软必须在VB.NET、C和C++扩展中实现,只是为了统一,但对于任何想要CLR的语言来说都是不必要的)但我不能确定。它们是一种语言扩展。正如您所怀疑的,编译器正在完
我猜这是一个编译器技巧,因为您甚至可以将它们作为声明类型的纯静态方法调用,因此必须是特定于语言的特性(微软必须在VB.NET、C和C++扩展中实现,只是为了统一,但对于任何想要CLR的语言来说都是不必要的)但我不能确定。它们是一种语言扩展。正如您所怀疑的,编译器正在完成所有工作,并生成IL代码,以静态方法显式调用扩展方法。这可以通过查看IL来验证
IL_0000: newobj instance void Sandbox.Program/Foo::.ctor()
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: call void Sandbox.Program::Bar(class Sandbox.Program/Foo)
在这里,我定义了一个类Foo
和一个扩展方法Bar()
,然后调用Foo.Bar()
Bar()
函数的转储显示,除了System.Runtime.CompilerServices.ExtensionAttribute之外,它没有做任何特殊的事情:
.method public hidebysig static void Bar(class Sandbox.Program/Foo foo) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
// Code size 1 (0x1)
.maxstack 8
IL_0000: ret
} // end of method Program::Bar
它们是一种语言扩展。正如您所怀疑的,编译器正在完成所有工作,并生成IL代码,以静态方法显式调用扩展方法。这可以通过查看IL来验证
IL_0000: newobj instance void Sandbox.Program/Foo::.ctor()
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: call void Sandbox.Program::Bar(class Sandbox.Program/Foo)
在这里,我定义了一个类Foo
和一个扩展方法Bar()
,然后调用Foo.Bar()
Bar()
函数的转储显示,除了System.Runtime.CompilerServices.ExtensionAttribute之外,它没有做任何特殊的事情:
.method public hidebysig static void Bar(class Sandbox.Program/Foo foo) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
// Code size 1 (0x1)
.maxstack 8
IL_0000: ret
} // end of method Program::Bar
正确,您可以在任何版本的.NET Framework上使用扩展方法,即使是“以前”引入的扩展方法,也只需在您的解决方案中创建适当的属性即可。谢谢,@dvnrrs。因此,如果我生成一个抽象语法树(AST),比如说使用System.CodeDOM,对于一个简单的静态类,它有一个静态方法,但没有第一个参数前缀为this
关键字,而是对静态方法应用ExtensionAttribute声明,然后我使用C#编译器编译AST,它不会生成扩展方法,对吗?@WaterCoolerv2 I think它会…在IL级别,ExtensionAttribute
是一个常规静态函数(它接受T
类型的参数)和T
类型的扩展方法之间唯一的区别。我在上面发布了我的示例扩展方法的IL转储,以便您可以查看。谢谢,@dvnrrs。我可能想错了,但是这难道不意味着扩展方法是内置在CLR中的吗?这正是我开始思考这一切的原因——我想知道我是否可以为一个具有ExtensionAttribute的类生成CodeCompileUnit/AST,并生成一个C扩展方法,而不必使用C语法。我还将在接下来的24小时或更长的时间内尝试它所以,@WaterCoolerv2我认为您应该能够在不使用C#的情况下生成扩展方法,是的。这并不意味着它内置于CLR中。CLR对“扩展方法”一无所知它只知道有一个方法上有一个属性。该属性告诉C#编译器在语法上将该方法视为扩展。正确的,您可以在任何版本的.NET Framework上使用扩展方法,即使是“以前”版本扩展方法的引入只是为了在解决方案中创建适当的属性。谢谢@dvnrrs。因此,如果我生成一个抽象语法树(AST),比如说使用System.CodeDOM,对于一个简单的静态类,它有一个静态方法,但没有第一个参数前缀为this
关键字,而是对静态方法应用ExtensionAttribute声明,然后我使用C#编译器编译AST,它不会生成扩展方法,对吗?@WaterCoolerv2 I think它会…在IL级别,ExtensionAttribute
是一个常规静态函数(它接受T
类型的参数)和T
类型的扩展方法之间唯一的区别。我在上面发布了我的示例扩展方法的IL转储,以便您可以查看。谢谢,@dvnrrs。我可能想错了,但是这难道不意味着扩展方法是内置在CLR中的吗?这正是我开始思考这一切的原因——我想知道我是否可以为一个具有ExtensionAttribute的类生成CodeCompileUnit/AST,并生成一个C扩展方法,而不必使用C语法。我还将在接下来的24小时或更长的时间内尝试它所以,@WaterCoolerv2我认为您应该能够在不使用C#的情况下生成扩展方法,是的。这并不意味着它内置于CLR中。CLR对“扩展方法”一无所知,它只知道有一个带有属性的方法。该属性告诉C#编译器在语法上将该方法视为扩展。