初始化单例后代的实例
Initialize instance of singleton descendant
在传统的单例中,您可以像这样初始化实例:
private static readonly Messages _instance = new Messages();
然后你通过 getter 访问它,像这样:
public static Messages Instance {
get {
return _instance;
}
}
在这种情况下,我们有一个 parent 和多个后代。
在parent我们有
protected static Base _instance;
public static Base Instance {
get {
return _instance;
}
}
在后代中,我们使用class构造函数来填充静态变量。
static Derived() {
_instance = new Derived();
}
这应该有效,因为 class 构造函数在首次引用 class 时被调用,然后才被使用。
出于某种原因,这不起作用。
Derived.Instance.Initialize();
失败,因为 Instance 为空,构造函数中的断点从未命中。
更新:调用了 Base 构造函数,但没有调用 Derived 构造函数。
这可能是因为在 class 上调用静态方法时触发了静态构造函数。我正在调用的静态方法在 parent 上,而不是在后代上。
它没有执行 Derived
构造函数,因为即使你写了 Derived.Instance
,C# 也很聪明,意识到 Instance
实际上是在 Base
上定义的 - 并且重新- 将调用写入 Base.Instance.Initialize()
,因此它不会初始化 Derived
。
无论如何,这似乎是一个非常糟糕的主意。当您创建并引用 Derived2
时会发生什么,它也设置了实例?现在你已经完蛋了 Derived.Instance
.
在不知道为什么你这样做的情况下,解决方法是在 Derived 上定义一个在 Derived.Instance
之前被外部引用的静态成员,或者创建一个 new static Derived Instance
在 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" };
}
}
The static method I am calling is on the parent, not the descendant.
这就是问题所在。 class 调用了基类的构造函数,因为调用了属于父类的静态方法。
在对后代调用静态方法之前,不会调用后代 class 构造函数。
Derived1.EmptyStaticMethod(); //This provokes the class constructor
Derived2.EmptyStaticMethod();
Derived1.Instance.Initialize(); // This now works.
在传统的单例中,您可以像这样初始化实例:
private static readonly Messages _instance = new Messages();
然后你通过 getter 访问它,像这样:
public static Messages Instance {
get {
return _instance;
}
}
在这种情况下,我们有一个 parent 和多个后代。
在parent我们有
protected static Base _instance;
public static Base Instance {
get {
return _instance;
}
}
在后代中,我们使用class构造函数来填充静态变量。
static Derived() {
_instance = new Derived();
}
这应该有效,因为 class 构造函数在首次引用 class 时被调用,然后才被使用。 出于某种原因,这不起作用。
Derived.Instance.Initialize();
失败,因为 Instance 为空,构造函数中的断点从未命中。
更新:调用了 Base 构造函数,但没有调用 Derived 构造函数。 这可能是因为在 class 上调用静态方法时触发了静态构造函数。我正在调用的静态方法在 parent 上,而不是在后代上。
它没有执行 Derived
构造函数,因为即使你写了 Derived.Instance
,C# 也很聪明,意识到 Instance
实际上是在 Base
上定义的 - 并且重新- 将调用写入 Base.Instance.Initialize()
,因此它不会初始化 Derived
。
无论如何,这似乎是一个非常糟糕的主意。当您创建并引用 Derived2
时会发生什么,它也设置了实例?现在你已经完蛋了 Derived.Instance
.
在不知道为什么你这样做的情况下,解决方法是在 Derived 上定义一个在 Derived.Instance
之前被外部引用的静态成员,或者创建一个 new static Derived Instance
在 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" };
}
}
The static method I am calling is on the parent, not the descendant.
这就是问题所在。 class 调用了基类的构造函数,因为调用了属于父类的静态方法。
在对后代调用静态方法之前,不会调用后代 class 构造函数。
Derived1.EmptyStaticMethod(); //This provokes the class constructor
Derived2.EmptyStaticMethod();
Derived1.Instance.Initialize(); // This now works.