【问题标题】:How can global function exist in C#?C#中如何存在全局函数?
【发布时间】:2011-11-09 21:35:48
【问题描述】:

当一切都在一个类中定义时,全局函数如何存在于 C# 中?我在 MSDN 上阅读OpCodes.Call 的文档,惊讶地看到以下措辞,

元数据标记携带足够的信息来确定调用是对静态方法、实例方法、虚拟方法、还是全局函数。

全局函数?它存在于 C# 中吗? (它绝对不是指static 方法,因为它与全局函数一起明确列出)。

【问题讨论】:

  • OpCodes.Call 并非特定于 C#,而是特定于 CLR
  • 如果我们告诉你我们就必须杀了你。 ;) 说真的,全局变量很糟糕——不要试图实现它们。
  • 为什么全局函数/方法定义不好?

标签: c# function global


【解决方案1】:

您不能在 C# 中使用全局函数,它只是语言的一部分。您必须在您选择的某个类上使用静态方法才能获得类似的功能。

但是,C# 并不是唯一使用 CLR 的语言。可以编写托管 C++,它可以具有全局函数。

【讨论】:

  • 但我在某处听说并读到过,当您编写托管 C++(或 C++/CLI)时,所有全局函数都被推入由编译器生成的静态类中。实际上,没有全局函数的概念。
  • 这可能发生在幕后,我不确定。如果您找到链接,请发布它。还有其他语言...我还没有完成完整的调查。
  • @Nawaz:这是一个与本次讨论无关的实现细节。重点是System.Reflection.Emit 与 IL 相关,而不是 C# 或托管 C++ 或任何其他编译成 IL 并位于 .NET Framework 之上的语言。托管 C++ 中是否存在全局函数或如何实现它们并不重要。重要的是,在解释 IL 的虚拟机或真实机器中,存在全局函数的概念,System.Reflection.Emit.OpCodes.Call 可用于发出可调用全局函数的 IL 操作码。
【解决方案2】:

在 Build 2014 会议上宣布,从 Roslyn 开始,您可以通过 using TypeName; 指令从类型中导入静态方法,这样您就不必使用 System.Math.Min(...) 了:

using System.Math;
...
var z = Min(x,y);

注意:到发布时,这变成了:

using static System.Math;

【讨论】:

  • 虽然从原始问题的意义上说,这仍然不是一个全局函数;它是一种语法速记,可让您免于键入“System.Math.Min”或“Math.Min”。就运行时而言,它仍然只是“System.Math”类上的一个静态函数
【解决方案3】:

因为System.Reflection.Emit.OpCodes.Call 与 C# 无关。它是关于发出 IL 操作码的。在 IL 中,有些功能在 C# 中不可用。全局函数就是这些特性之一。

【讨论】:

    【解决方案4】:

    我想问题是,这是 IL 注入操作,但 IL 不是绝对只是关于 C#。换句话说,它是为了支持支持全局函数的语言。

    【讨论】:

    • @Nawaz:我相信这是关于动态语言,例如 IronPython、F#(不太确定)。可以在此处找到有关方法动态生成的有趣内容:msdn.microsoft.com/en-us/library/…
    【解决方案5】:

    您所指的文档适用于 .net。 C# 不支持全局函数,但 .net 可以。

    【讨论】:

    • 究竟如何?请在你的回答中更加慷慨。 :-)(我是 .Net 新手)。
    • .net 是一个平台。 C# 编译器存在于该平台之上,但 .net 旨在提供比 C# 更多的服务。 C# 设计者选择在该语言的设计中不满足全局功能,但构建在 .net 上的其他语言可以选择这样做。事实上,.net 充满了各种语言所不具备的功能。
    【解决方案6】:

    C# 不支持 MSIL 的所有功能。全局函数就是其中之一。 VB.Net、F#、IronPython 或其他一些语言都可以使用此功能以及 C# 编译器未生成的其他功能。

    【讨论】:

    • 他们可能会,他们可能不会。没关系。关键是 IL 支持它们,因此解释 IL 的虚拟机或真实机器都支持它们。编译成 IL 的其他语言是否这样做,或者这些语言的编译器是否将这些全局函数转换为编译后的 IL 中的全局函数,都无关紧要。
    【解决方案7】:

    我只是覆盖了我之前的答案...

    下面是每个在 IL DASM 中的样子及其相关代码:

    // Static Method
    IL_0001:  call       void testapp.Form1::Test()
    
    // Instance Method
    IL_0001:  call       instance void testapp.Form1::Test()
    
    // Virtual Method
    IL_0001:  callvirt   instance void testapp.Form1::Test()
    
    // Global Function
    IL_0000:  call       void testapp.Test()
    

    因此,要回答您的问题,在 C# 的最后一种方法中没有直接生成元数据令牌的方法。我必须在 C++ 中创建最后一个。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      • 2023-01-29
      • 2012-06-04
      • 1970-01-01
      相关资源
      最近更新 更多