Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.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# .Net:当访问常量时是否调用静态构造函数?_C#_Static_Static Constructor - Fatal编程技术网

C# .Net:当访问常量时是否调用静态构造函数?

C# .Net:当访问常量时是否调用静态构造函数?,c#,static,static-constructor,C#,Static,Static Constructor,这就是我的想法 public class MyClass { public const string MyConstant = "MyConstantValue"; private static MyClass DefaultInstance; static MyClass() { DefaultInstance = new MyClass(); } } ... NotificationService.RegisterForNot

这就是我的想法

public class MyClass
{
    public const string MyConstant = "MyConstantValue";

    private static MyClass DefaultInstance;

    static MyClass()
    {
         DefaultInstance = new MyClass();
    }
}

...

NotificationService.RegisterForNotification(MyClass.MyConstant, Callback);

这会起作用吗?还是我需要使用类似于
静态只读属性字段的东西来触发静态构造函数?

不,您不需要这样。加载类时调用静态构造函数。

在创建第一个实例或引用任何静态成员之前,会自动调用静态构造函数。请看这里:


顺便说一句,常量字段本质上是静态的,但正如所指出的,它们可能(也可能会)被值本身所取代。

使用常量不一定会导致成员访问,这会导致调用静态构造函数。编译器可以(鼓励,甚至)在编译时替换常量的值

您建议的
static readonly
解决方案应该可以,尽管
readonly
建议的是字段,而不是属性。属性在没有setter时是只读的,不涉及
readonly
关键字

一个简单的例子:

class HasSConstructor
{
    internal const int Answer = 42;
    static HasSConstructor()
    {
        System.Console.WriteLine("static constructor running");
    }
}

public class Program
{
    public static void Main()
    {
        System.Console.WriteLine("The answer is " + HasSConstructor.Answer.ToString());
    }
}
.NET 4.0下的输出:

答案是42


静态构造函数从不运行

如果您只是访问公共常量,则不会调用静态构造函数。例如,考虑这个类:

class Testo
{
    public const string MyValue = "Hello, world";
    public static readonly int xyzzy;

    static Testo()
    {
        Console.WriteLine("In static constructor");
        xyzzy = 27;
    }
}
现在,在另一个类中,执行:

Console.WriteLine(Testo.MyValue);
Console.WriteLine(Testo.xyzzy);
您的输出将是:

Hello, world
In static constructor
27
常量在编译时从类中提升。因此,
Testo.MyValue
的值在运行时不引用
Testo
类。在调用需要初始化的东西之前,不会调用静态构造函数


因此,是的,如果您想确保调用构造函数,您需要访问类似于
静态只读的东西。

是的,什么时候加载了类?或者存在对该类的引用(例如访问静态成员、实例化对象、强制转换到该类)或者手动加载该类。@Nam:这不对。如果类型未标记为
beforefieldinit
,并且带有静态构造函数的C类未标记为
beforefieldinit
,则不允许强制转换或手动加载类来运行类型初始值设定项。如何手动加载类?强制转换不一定调用静态构造函数:
公共静态显式操作符Foo(Bar){returnnull;}
。给这个演员打电话并不重要,它是“紧接着之前”。带有静态构造函数的C#类永远不会在forefieldinit
之前标记为
。但是使用常量(在.NET中称为
literal
)无法访问静态成员。您对属性/字段注释的看法是正确的,我在大多数情况下倾向于不区分,这可能会让我有一天陷入麻烦。