gpt4 book ai didi

c# - 为什么在调用非静态方法时会调用结构中的静态构造函数?

转载 作者:行者123 更新时间:2023-12-04 10:40:47 24 4
gpt4 key购买 nike

C# 规范读到

the execution of a static constructor for a struct type is triggered by the first of the following events to occur within an application domain:

  • A static member of the struct type is referenced.
  • An explicitly declared constructor of the struct type is called.


在以下代码中,尽管上述事件均未发生,但仍会调用静态构造函数。
struct Notebook
{
static Notebook() => Console.WriteLine("Static Ctor");

public void Method() => Console.WriteLine("Method");
}



class Program
{
static void Main()
{
Notebook notebook;

notebook.Method();
}
}

当在结构中声明的自动属性在 void Main() 中赋值时,同样适用。
在这种情况下,究竟是什么使静态构造函数被调用?

最佳答案

在我看来,这种差异从根本上是 C# language specification 之间的冲突。 (最新的非草案规范,即 C# 5.0,已链接,但其他版本在这方面基本相同)和 the Common Language Infrastructure specification .

具体来说,语言规范提供了您提到的触发器,但 CLI 规范包含对未标有 BeforeFieldInit 的类型的描述。标志(就像这里的情况):

The semantics of when and what triggers execution of such type initialization methods, is as follows:

4. If not marked BeforeFieldInit then that type’s initializer method is executed at (i.e., is triggered by):
    a. first access to any static field of that type, or
    b. first invocation of any static method of that type, or
    c. first invocation of any instance or virtual method of that type if it is a value type or
    d. first invocation of any constructor for that type.



(我的重点)

换句话说,对于运行时,规则是明确地调用任何类型的实例方法将导致调用静态构造函数(即“类型初始值设定项”)。这正是您的程序的行为方式。

C# 规范中的语言坚持了这么久,从早期版本的规范一直到最新发布的语言版本(技术上是“草案”规范,但仍然是规范的),我很难认为这种差异是一个简单的疏忽。当然可能是(除非来自语言设计者的输入)。但我认为,尽管 CLI 的规则如此,但我认为语言设计者决定将限制降至最低(因为从理论上讲,C# 语言可以针对其他类似的平台,可能不像 CLI 那样限制的平台),并且只是与差异共存。

毕竟,C# 程序的 CLI 实现遵循其规则而不是 C# 规则,对任何人来说都不可能有问题。当一个不访问静态成员的方法被调用时,程序实际上依赖于不被调用的静态构造函数应该是非常罕见的,并且可以说是非常糟糕的设计。

关于c# - 为什么在调用非静态方法时会调用结构中的静态构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59938630/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com