Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 扩展方法是CLR的语言特性还是CLR的语言特性?_C#_.net_Clr - Fatal编程技术网

C# 扩展方法是CLR的语言特性还是CLR的语言特性?

C# 扩展方法是CLR的语言特性还是CLR的语言特性?,c#,.net,clr,C#,.net,Clr,C#3为我们带来了扩展方法 但是,其他语言(如VB.NET)也通过在必须在VB.NET模块中声明的方法之上指定属性声明来实现扩展方法 此外,还可以在C++/CLI中使用扩展方法 所以,我想知道扩展方法是语言特性还是CLR内置的特性 我猜这是一个编译器技巧,因为您甚至可以将它们作为声明类型的纯静态方法调用,因此必须是特定于语言的特性(微软必须在VB.NET、C和C++扩展中实现,只是为了统一,但对于任何想要CLR的语言来说都是不必要的)但我不能确定。它们是一种语言扩展。正如您所怀疑的,编译器正在完

C#3为我们带来了扩展方法

但是,其他语言(如VB.NET)也通过在必须在VB.NET模块中声明的方法之上指定属性声明来实现扩展方法

此外,还可以在C++/CLI中使用扩展方法

所以,我想知道扩展方法是语言特性还是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#编译器在语法上将该方法视为扩展。