【问题标题】:Are extension methods a language feature or that of the CLR?扩展方法是语言特性还是 CLR 的特性?
【发布时间】:2014-01-20 19:26:35
【问题描述】:

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

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

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

那么,我想知道扩展方法是语言特性还是 CLR 中内置的特性?

我猜这是一个编译器技巧,因为您甚至可以将它们作为声明它们的类型的普通静态方法调用,因此必须是特定于语言的功能(并且必须由 Microsoft 在 VB.NET、C# 中实现和 C++ 扩展只是为了统一起见,但对于任何其他想要针对 CLR 的语言来说都不是必需的),但我不能确定。

【问题讨论】:

    标签: c# .net clr


    【解决方案1】:

    它们是语言扩展。正如您所怀疑的,编译器正在完成所有工作并生成将扩展方法显式调用为静态方法的 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,它不会生成扩展方法,对吧?
    • @WaterCoolrv2 我认为它会...ExtensionAttribute 是在 IL 级别上,采用 T 类型参数的常规静态函数和扩展方法之间的唯一区别输入T。我在上面发布了我的示例扩展方法的 IL 转储,以便您查看。
    • 谢谢,@dvnrrs。我可能想错了,但这是否表明扩展方法内置在 CLR 中?这就是让我开始思考这一切的真正原因——我想知道是否可以为具有 ExtensionAttribute 的类生成 CodeCompileUnit/AST,并在不使用 C# 语法的情况下生成 C# 扩展方法。我也会在接下来的 24 小时左右尝试一下。
    • @WaterCoolrv2 我认为您应该能够在不使用 C# 的情况下生成扩展方法,是的。这并不意味着它内置在 CLR 中。 CLR 对“扩展方法”一无所知,它只知道有一个带有属性的方法。该属性告诉 C# 编译器在语法上将该方法视为扩展。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-25
    • 1970-01-01
    • 2018-12-12
    • 2023-03-06
    • 1970-01-01
    • 2016-05-09
    • 2011-05-05
    相关资源
    最近更新 更多