2012-02-01 79 views
1

我只是試圖實現Singleton模式來的WinForms,以便只有一個窗體的實例停留在應用程序生命對象引用和異常,但我面對困難返回從方法同時

我想拋出異常如果單例的實例存在並且同時返回相同的實例引用。

SingletonForm.cs

public class SingletonForm : BaseFormcs 
{ 
    private static SingletonForm _instance; 
    //To stop new keyword from instantiation 
    private SingletonForm() 
    { } 
    public static SingletonForm GetInstance() 
    { 
     if (_instance == null) 
      return _instance = new SingletonForm(); 

     else 
     { 
      throw new Exception("Form already exists"); // execution returns from here 
      return _instance; // Warning : Unreachable code detected 
      //I also want to return instance reference. 
     } 

    } 
} 
+3

爲什麼要在這種情況下拋出異常?這對我來說根本沒有多大意義。 – BrokenGlass 2012-02-01 15:55:43

+2

請注意您的單例實現不是線程安全的。 – 2012-02-01 15:56:39

+1

這個問題很難保證答案,因爲它似乎是一個非常糟糕的做法,但您可以使用out參數。 public static SingletonForm GetInstance(out Exception ex){} – Lloyd 2012-02-01 15:57:56

回答

6

你要麼拋出一個異常,或返回一個實例。在Singleton的情況下,不應拋出異常,只要返回實例(如果存在)。

Singleton模式不應該阻止你(甚至警告你)多次調用GetInstance。它應該只返回第一次創建的同一個實例。

我只是想可能是有時我可能需要同時使用這兩種 這就是爲什麼我問

拋出異常從函數立即返回,因爲這意味着發生意外錯誤。在另一種情況下,您可能想引發異常,但前提是某些條件爲真(例如,參數驗證失敗)。否則,您返回一個值。這裏有一個例子:

public int SomeFunction(String someArgument) 
{ 
    if (someArgument == null) throw new ArgumentNullException("someArgument"); 
    int retVal = 0; 
    //Some code here 
    return retVal; 
} 
+0

「不應拋出異常,只要返回實例存在即可。」好吧.. – 2012-02-01 16:10:26

+0

我添加了一些關於「同時使用」的一般性建議。 – 2012-02-01 16:29:50

+0

謝謝你..請檢查我的問題2 – 2012-02-01 17:24:41

2

從設計的角度來看,不,你沒有。異常應該表示系統需要恢復的嚴重的,意外的錯誤。你正在談論使用它作爲錯誤代碼。如果你打算這樣做,不要拋出異常 - 通過在你的單例中設置一個標誌或返回null或其他東西來指出問題。

但是,在您的具體情況下,只需擺脫異常邏輯。單例設計模式旨在成爲全局變量的存儲庫,因此預計公共靜態實例將被多次調用(實際上,單例的許多用戶傾向於在其代碼庫中的每個類中使用它)。

+0

「通過在你的單身上設置一個標誌表明一個問題」詳細說明這一點,請 – 2012-02-01 16:13:39

+1

含義,而不是拋出異常,您可以保留一個靜態實例計數器變量,每次有人調用GetInstance()時都會增加。在名爲TooManyAccesses的Singleton上公開一個靜態布爾屬性,並在實例計數器不止一個時將其設置爲true。沿着這些線的東西。 – 2012-02-01 16:23:40

2

我正在假設你有一個實際需要知道它是否是新實例的情況,並且它將在返回後改變執行路徑。一種方法是(雖然我不寒而慄)輸入異常(選項1)。但更有可能的是,您希望使用選項2來簡單地分支返回值。

public class SingletonForm : BaseFormcs 
{ 
    private static SingletonForm _instance; 
    //To stop new keyword from instantiation 
    private SingletonForm() 
    { } 
    // ------- Option #1 
    // Use an OUT parameter for the instance, so it's set before the exception 
    public static void GetInstance(out SingletonForm form) 
    { 
     if (_instance == null) 
     { 
      _instance = new SingletonForm(); 
      form = _instance; 
      return; 
     } 
     form = _instance; 
     throw new Exception("Form already exists"); // execution returns from here 
     // return isn't needed, since you threw an exception. 
     // You really, really shouldn't do this. Consider instead... 
    } 

    // -------- Option #2 
    // Same as above, but the return value tells you whether it's shiny and new 
    public static bool GetInstance(out SingletonForm form) 
    { 
     if (_instance == null) 
     { 
      _instance = new SingletonForm(); 
      form = _instance; 
      return true; // yes, you created a new one 
     } 
     form = _instance; 
     return false; // no, you used an extant one 
    } 
} 

這第二個選項可能是你最好的選擇,因爲它是沿着你會在Dictionary.TryGetValue看到線(KEY鍵,超時值值)以上。

+0

感謝您的輸入...... :-) – 2012-02-01 17:41:10