2016-11-16 78 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.