静态类初始化

6
在.Net中,静态类内部是否创建一个对象,还是根本不创建任何对象。根据Microsoft文档所述,与所有类类型一样,当引用该类的程序加载时,.NET Framework公共语言运行时(CLR)将加载静态类的类型信息。程序不能指定类何时加载。但是,在您的程序中首次引用该类之前,它保证已经被加载,并且其字段已经初始化并调用了其静态构造函数。静态构造函数只会调用一次,静态类将在应用程序域的生命周期内一直存在于内存中。我们能否说在这里隐式地创建了一个对象?我相信仅写静态类不会为其创建内存,除非静态类或其成员在代码中被引用。如果我错了,请纠正我。

你好!你的问题是否得到了回答?https://dev59.com/hmw15IYBdhLWcg3wSJk3 - user8214728
1
Venkata,你的意思是“这回答了你的问题”吗? :) - Fabjan
“它的静态构造函数在程序中第一次引用该类之前被调用。” CLR 仅创建一个静态类的实例。 - Krivitskiy Grigoriy
1
只有在其成员被使用时才会创建静态对象,请查看此代码此处 - Fabjan
静态类型从未被“创建”,但正如引用的文档所述,它们是“初始化”的。这种初始化发生在类型的成员首次使用之前。 - Lasse V. Karlsen
显示剩余5条评论
1个回答

10
如果我正确理解你的问题,你想知道如果在代码中没有调用静态类对象,是否会初始化它。
因此,我刚刚创建了一个带有静态类的简单控制台应用程序,并在构造函数中添加了一些Console.WriteLine命令,就像这样:
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Hello World!");
    }
}
static class SomeClass
{
    static SomeClass()
    {
        Console.WriteLine(GetId(1));
        Console.WriteLine(GetId(2));
    }
    public static string GetId(int Id) { return Id.ToString(); }
}

我得到了以下输出:
Hello World!

然后我使用静态类的访问权限来运行程序:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Hello World!");
        Console.WriteLine(SomeClass.GetId(3));
    }
}
static class SomeClass
{
    static SomeClass()
    {
        Console.WriteLine(GetId(1));
        Console.WriteLine(GetId(2));
    }
    public static string GetId(int Id) { return Id.ToString(); }
}

在这里,我的控制台输出是:

Hello World!
1
2
3

这意味着如果您的程序中没有调用该类,则不会进行初始化并且对象也不会相应地被创建。 但是,如果您访问该类,则对象将在代码中第一次访问之前被创建,这意味着构造函数在首次调用时创建它,而不需要单独的初始化,例如: var _someClass = new SomeClass();,在首次访问之前就已经创建,且仅在程序的生命周期中创建一次。无论您在程序中调用多少次它,自从首次初始化以来,实例将一直存在于软件运行期间,因此,如果我在整个程序中使用该SomeClass的函数或属性,无论我使用多少次或者在哪里使用,我都会重用同一个实例。如果您的程序中没有调用该类,则根本不会创建实例,我想这就是Microsoft文档所指的内容。

非常感谢您的努力!但是,可以保证在程序中第一次引用该类之前,它已被加载并初始化其字段,并调用了其静态构造函数。-- 这种情况与观察到的结果相反。 - Arun Kola
实际上并不是这样的,因为“在程序中第一次引用类之前”意味着如果它被实际引用,那么在从程序中调用该引用之前,它也保证已经初始化。但据我理解,它并没有说明这种情况:如果你的程序根本没有引用这个静态类,那么显然它就没有被初始化,这在逻辑上是有意义的。 - Irakli
@ArunKola 实际上,对于当前版本的 .Net,Irakli 的回答仍然是正确的。如果未引用静态类,则不会调用来自静态构造函数的代码。 - Dash83
不错,有趣且详尽的解决方案。 - levi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接