请给我解释一下静态构造函数的用法。为什么,什么时候我们要创建一个静态构造函数,它是否可能重载一个?


当前回答

来自静态构造函数(c#编程指南):

A static constructor is used to initialize any static data, or to perform a particular action that needs performed once only. It is called automatically before the first instance is created or any static members are referenced. Static constructors have the following properties: A static constructor does not take access modifiers or have parameters. A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced. A static constructor cannot be called directly. The user has no control on when the static constructor is executed in the program. A typical use of static constructors is when the class is using a log file and the constructor is used to write entries to this file. Static constructors are also useful when creating wrapper classes for unmanaged code, when the constructor can call the LoadLibrary method.

其他回答

来自静态构造函数(c#编程指南):

A static constructor is used to initialize any static data, or to perform a particular action that needs performed once only. It is called automatically before the first instance is created or any static members are referenced. Static constructors have the following properties: A static constructor does not take access modifiers or have parameters. A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced. A static constructor cannot be called directly. The user has no control on when the static constructor is executed in the program. A typical use of static constructors is when the class is using a log file and the constructor is used to write entries to this file. Static constructors are also useful when creating wrapper classes for unmanaged code, when the constructor can call the LoadLibrary method.

不,你不能让它过载;静态构造函数对于初始化与类型相关的任何静态字段(或任何其他每种类型的操作)非常有用——特别是对于将所需的配置数据读入只读字段等非常有用。

它在第一次需要时由运行时自动运行(那里的确切规则很复杂(参见“beforefieldinit”),并且在CLR2和CLR4之间有微妙的变化)。除非滥用反射,否则它保证最多运行一次(即使两个线程同时到达)。

可以使用静态构造函数初始化静态字段。在使用这些字段之前,它在一个不确定的时间运行。微软的文档和许多开发人员警告说,类型上的静态构造函数会带来巨大的开销。为了获得最佳性能,最好避免使用静态构造函数。 更新:你不能在同一个类中使用多个静态构造函数,但是你可以使用(最多)一个静态构造函数的其他实例构造函数。

1.它只能访问类的静态成员。

原因:非静态成员特定于对象实例。如果允许静态构造函数作用于非静态成员,它将反映所有对象实例中的变化,这是不切实际的。

2.在静态构造函数中不应该有参数。

原因:因为它将被CLR调用,所以没有人可以将参数传递给它。 3.只允许一个静态构造函数。

原因:重载需要两个方法在方法/构造函数定义方面有所不同,这在静态构造函数中是不可能的。

4.它不应该有访问修饰符。

原因:同样的原因是对静态构造函数的调用是由CLR而不是由对象进行的,不需要对它有访问修饰符

当静态字段相互依赖,初始化顺序很重要时,静态构造函数也非常有用。如果您通过一个改变字段顺序的格式化器/美化器运行代码,那么您可能会发现自己在意想不到的地方得到了空值。

示例:假设我们有这样一个类:

class ScopeMonitor
{
    static string urlFragment = "foo/bar";
    static string firstPart= "http://www.example.com/";
    static string fullUrl= firstPart + urlFragment;
}

当您访问fullUr时,它将是“http://www.example.com/foo/bar”。

几个月后,您将清理代码并按字母顺序排列字段(假设它们是一个更大的列表的一部分,因此您没有注意到问题)。你有:

class ScopeMonitor
{
    static string firstPart= "http://www.example.com/";
    static string fullUrl= firstPart + urlFragment;
    static string urlFragment = "foo/bar";
}

你的fullUrl值现在只是“http://www.example.com/”,因为urlFragment在设置fullUrl时还没有初始化。不好的。所以,你添加一个静态构造函数来处理初始化:

class ScopeMonitor
{
    static string firstPart= "http://www.example.com/";
    static string fullUrl;
    static string urlFragment = "foo/bar";

    static ScopeMonitor()
    {
        fullUrl= firstPart + urlFragment;

    }
}

现在,不管字段的顺序是什么,初始化总是正确的。