2016-11-16 61 views
0

的情况下在传统的单,你可以初始化实例,像这样:初始化单后裔

private static readonly Messages _instance = new Messages(); 

然后你通过一个getter访问它,就像这样:

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

在这种情况下,我们有一个父母和多个后代。

在父,我们有

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

在后代中,我们使用类的构造函数来填充静态变量。

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

这应该起作用,因为在使用类之前首先引用类时调用类构造函数。 由于某种原因,这不起作用。

Derived.Instance.Initialize(); 

失败,因为实例为空,并且构造函数中的断点永远不会被命中。

更新:基础构造函数被调用,但派生构造函数没有。 这可能是因为在类上调用静态方法时触发静态构造函数。我所调用的静态方法是父类,而不是后代。

回答

1

,因为即使你写Derived.Instance它不执行Derived构造函数,C#正在聪明,意识到Instance实际上是定义在Base - 并重新写入呼叫被Base.Instance.Initialize(),所以它不初始化Derived

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

不知道为什么你这样做,解决方法是定义要Derived.Instance之前,外部参照上派生的静态成员,或创建一个Derivednew static Derived Instance

下面是一个例子来证明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" }; 
    } 
} 
+0

>当您创建和引用Derived2时会发生什么? – BWhite

+0

我认为你是正确的关于实例得到破坏,但它实际上工作。每个班级创建并保存正确的实例。 – BWhite

+0

@BWhite你确定吗?我刚刚测试过它进行仔细检查,它肯定会被覆盖。看到我的编辑 – Rob

0

静态方法我打电话是父,没有后代。

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

直到在后代上调用一个静态方法时才会调用后代类构造函数。

Derived1.EmptyStaticMethod(); //This provokes the class constructor 
Derived2.EmptyStaticMethod(); 
Derived1.Instance.Initialize(); // This now works.