简体   繁体   English

为什么这个 singleton 代码示例中有两个构造函数

[英]Why two constructors in this singleton code example

I need to implement a singleton pattern in code and found this version (#4) that seems to fit my needs.我需要在代码中实现 singleton 模式, 发现这个版本 (#4)似乎符合我的需要。

public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();

// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Singleton()
{
}

private Singleton()
{
}

public static Singleton Instance
{
    get
    {
        return instance;
    }
}

} }

Why does the example have two constructors?为什么这个例子有两个构造函数? I did put Debug.Write in each of the constructors and saw that both were executed on class initialition.我确实将Debug.Write放入每个构造函数中,并看到它们都是在 class 初始化时执行的。

Do I need to keep both?我需要同时保留两者吗? Which one is preferred to use for my own code?哪一个更适合用于我自己的代码?

If you have a type that is not marked as beforefieldinit , then it's static constructor will be called right before you need it, which means, if you don't use your singleton, it won't get instantiated. 如果您的类型未标记为beforefieldinit ,则将在需要它之前立即调用它的静态构造函数,这意味着,如果您不使用单例,则不会实例化它。

To be more specific, the specification states that 更具体地说,该规范指出

The semantics of when and what triggers execution of such type initialization methods, is as follows: The semantics of when and what triggers execution of such type initialization methods, is as follows: 何时和什么触发此类初始化方法的执行的语义如下:何时和什么触发此类初始化方法的执行的语义如下:

  1. A type can have a type-initializer method, or not. 类型可以具有类型初始化器方法,也可以不具有。
  2. A type can be specified as having a relaxed semantic for its type-initializer method (for convenience below, we call this relaxed semantic BeforeFieldInit). 可以将类型指定为具有其类型初始化器方法的宽松语义(为方便起见,在下文中,我们将此宽松语义称为BeforeFieldInit)。
  3. If marked BeforeFieldInit then the type's initializer method is executed at, or sometime before, first access to any static field defined for that type. 如果标记为BeforeFieldInit,则在首次访问为该类型定义的任何静态字段时或之前执行该类型的初始化方法。
  4. If not marked BeforeFieldInit then that type's initializer method is executed at (ie, is triggered by): 如果未标记BeforeFieldInit,则在以下位置执行该类型的初始化方法(即,由触发):

a. 一种。 first access to any static field of that type, or 首次访问该类型的任何静态字段,或者

b. b。 first invocation of any static method of that type, or 首次调用该类型的任何静态方法,或者

c. C。 first invocation of any instance or virtual method of that type if it is a value type or 首次调用该类型的任何实例或虚拟方法(如果它是值类型)或

d. d。 first invocation of any constructor for that type. 首次调用该类型的任何构造函数。

The non-static constructor is needed so that compiler does not create default constructor with no parameters. 需要非静态构造函数,以便编译器不会创建不带参数的默认构造函数。

If a class contains no instance constructor declarations, a default instance constructor is automatically provided. 如果一个类不包含实例构造函数声明,则会自动提供一个默认的实例构造函数。 That default constructor simply invokes the parameterless constructor of the direct base class. 该默认构造函数仅调用直接基类的无参数构造函数。 If the direct base class does not have an accessible parameterless instance constructor, a compile-time error occurs. 如果直接基类没有可访问的无参数实例构造函数,则会发生编译时错误。 If the class is abstract then the declared accessibility for the default constructor is protected. 如果该类是抽象的,则默认构造函数的声明可访问性将受到保护。 Otherwise, the declared accessibility for the default constructor is public. 否则,默认构造函数的声明可访问性为public。 Thus, the default constructor is always of the form 因此,默认构造函数始终为以下形式

The static constructor is called when your class is called the very first time, no matter if by a static call like SingleTon.MyMember or by creating a new instance of it. 第一次调用类时将调用静态构造函数,而不管是通过诸如SingleTon.MyMember类的静态调用还是通过创建它的新实例。 The other one is always called, when you instantiate a new instance (which in case of a singleton however is only once). 实例化一个新实例时,总是调用另一个实例(但是,在单例的情况下,只有一个实例)。 You should set the access-modifier of the latter to private to avoid creating instances. 您应该将后者的访问修饰符设置为private,以避免创建实例。

EDIT: IF you have a singleton-class you won´t need both constructor. 编辑:如果您有一个单例类,则不需要两个构造函数。 All your initializations can be done by the default one, where you set all important members of that instance whereas the static one can be omitted. 默认情况下,所有初始化都可以完成,默认情况下,您可以设置该实例的所有重要成员,而静态成员可以省略。

If you leave the private constructor out.如果您将私有构造函数排除在外。 The default constructor is public.默认构造函数是公共的。 And you will not have a singleton. That's why you need to explicitly also have a private constructor.而且你不会有 singleton。这就是为什么你还需要明确地拥有一个私有构造函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM