Возврат ссылки на объект и исключения из метода одновременно - PullRequest
1 голос
/ 01 февраля 2012

Я только что попытался внедрить шаблон 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 ]

6 голосов
/ 01 февраля 2012

Вы либо генерируете исключение, либо возвращаете экземпляр. В случае синглтона исключение не должно создаваться, просто вернуть экземпляр, если он существует.

Шаблон Singleton не должен мешать вам (или даже предупреждать) о необходимости многократного вызова GetInstance. Он должен просто вернуть тот же экземпляр, который был создан в первый раз.

Я просто подумал, что может быть когда-нибудь мне понадобится использовать оба одновременно вот почему я спросил

Выдача исключения немедленно возвращается из функции, поскольку это означает, что произошла непредвиденная ошибка. В другой ситуации вам может потребоваться сгенерировать исключение, но только в том случае, если выполняется какое-либо условие (например, сбой проверки аргумента). В противном случае вы возвращаете значение. Вот пример:

public int SomeFunction(String someArgument)
{
    if (someArgument == null) throw new ArgumentNullException("someArgument");
    int retVal = 0;
    //Some code here
    return retVal;
}
2 голосов
/ 01 февраля 2012

Я работаю в предположении, что у вас есть случай, когда вам действительно нужно знать, является ли это новым экземпляром, и что он собирается изменить ваш путь выполнения после возврата. Одним из способов является (хотя я содрогаюсь от этого) использование исключений (вариант 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).

2 голосов
/ 01 февраля 2012

С точки зрения дизайна, нет. Исключение должно представлять серьезную непредвиденную ошибку, после которой ваша система должна быть восстановлена. Вы говорите об использовании его в качестве кода ошибки. Если вы собираетесь это сделать, не выбрасывайте исключение - укажите проблему, установив флаг на синглтоне или вернув ноль или что-то еще.

Однако в вашем конкретном случае просто избавьтесь от логики исключений. Шаблон проектирования синглтона предназначен для использования в качестве хранилища глобальных переменных, поэтому ожидается, что открытый статический экземпляр будет вызываться более одного раза (на самом деле, многие пользователи синглтона стремятся использовать его практически в каждом классе в своей базе кода). ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...