2012-02-01 87 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