同时从方法返回对象引用和异常

时间:2012-02-01 15:52:38

标签: c# singleton

我只是尝试将单例模式实现为WinForms,因此只有一个表单实例停留在应用程序生命周期中,但我遇到了困难

如果存在singleton实例并且同时返回相同的实例引用,我想抛出异常。

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 个答案:

答案 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值)中看到的内容。

相关问题