0

In a traditional singleton, you can initialize the instance like so:

private static readonly Messages _instance = new Messages();

Then you access it via a getter, like so:

    public static Messages Instance {
        get {
            return _instance;
        }
    }

In this case, we have a parent and multiple descendants.

In the parent we have

    protected static Base _instance;
    public static Base Instance {
        get {
            return _instance;
        }
    }

In the descendant, we use the class constructor to populate the static variable.

    static Derived() {
        _instance = new Derived();
    }

This should work because the class constructor is called when the class is first referenced, before it is used. For some reason, this is not working.

   Derived.Instance.Initialize();

fails because Instance is null and the breakpoint in the constructor is never hit.

Update: The Base constructor gets called, but the Derived constructor does not. This may be because the static constructor is triggered when a static method is called on the class. The static method I am calling is on the parent, not the descendant.

4

2 回答 2

1

它没有执行Derived构造函数,因为即使您编写了Derived.Instance,C# 也很聪明,并意识到它Instance实际上是在 - 上定义的Base- 并将调用重写为 be Base.Instance.Initialize(),因此它不会初始化Derived

无论如何,这似乎是一个非常糟糕的主意。当您创建和引用Derived2也设置实例时会发生什么?现在你已经走了,大打折扣Derived.Instance

在不知道为什么要这样做的情况下,解决方法是在 Derived 上定义一个静态成员,该成员在之前外部引用Derived.Instance,或者创建一个new static Derived Instanceon Derived

这是一个示例来演示Dervied2将覆盖实例:

void Main()
{
    //Prints null
    Console.WriteLine(Derived.Instance?.Name);

    //Prints Derived
    var a = Derived.InitDerived;
    Console.WriteLine(Derived.Instance?.Name);

    //Prints Derived2
    var b = Derived2.InitDerived;
    Console.WriteLine(Derived.Instance?.Name);
}

public class Base
{
    public string Name { get; set; }
    protected static Base _instance;
    public static Base Instance
    {
        get
        {
            return _instance;
        }
    }
}
public class Derived : Base
{
    public static int InitDerived = 1;
    static Derived()
    {
        _instance = new Derived() { Name = "Derived" };
    }
}

public class Derived2 : Base
{
    public static int InitDerived = 2;
    static Derived2()
    {
        _instance = new Derived()  { Name = "Derived2" };
    }
}
于 2016-11-16T04:11:43.633 回答
0

我调用的静态方法是在父级上,而不是在后代上。

这就是问题所在。调用了基类的类构造函数,因为调用了属于父类的静态方法。

在对后代调用静态方法之前,不会调用后代类构造函数。

Derived1.EmptyStaticMethod(); //This provokes the class constructor
Derived2.EmptyStaticMethod();
Derived1.Instance.Initialize(); // This now works.
于 2016-11-17T02:54:30.837 回答