我只是尝试将单例模式实现为WinForms,因此只有一个表单实例停留在应用程序生命周期中,但我遇到了困难
如果存在singleton实例并且同时返回相同的实例引用,我想抛出异常。
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.
}
}
}
答案 0 :(得分:6)
您要么抛出异常,要么返回实例。对于Singleton,不应抛出异常,只返回实例(如果存在)。
Singleton模式不应该阻止你(甚至警告你)多次调用GetInstance。它应该只返回第一次创建的同一个实例。
我只是觉得可能有时我可能需要同时使用这两种方法 那就是我问的原因
抛出异常会立即从函数返回,因为这意味着发生意外错误。在另一种情况下,您可能希望抛出异常,但仅在某些条件为真时(例如,参数验证失败)。否则,返回一个值。这是一个例子:
public int SomeFunction(String someArgument)
{
if (someArgument == null) throw new ArgumentNullException("someArgument");
int retVal = 0;
//Some code here
return retVal;
}
答案 1 :(得分:2)
从设计的角度来看,不,你没有。异常应表示系统需要恢复的严重的,未预料到的错误。您正在谈论将其用作错误代码。如果您要这样做,请不要抛出异常 - 通过在单例上设置标志或返回null或其他内容来指示问题。
但是,在您的具体情况下,只需摆脱异常逻辑。单例设计模式旨在成为全局变量的存储库,因此预计公共静态实例将被多次调用(实际上,单例的许多用户倾向于在其代码库中的几乎每个类中使用它) )。
答案 2 :(得分: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键,输出VALUE值)中看到的内容。