Какой шаблон выбрать при попытке получить успех / неудачу и объект из метода? - PullRequest
1 голос
/ 01 марта 2012

Я обсуждаю различные методы реализации с коллегой

Альтернатива A

User user;
if (users.TryGet(1, out user))
    Console.WriteLine(user.ToString()); 
else
    Console.WriteLine("Failed to get user.."); 

Альтернатива B

ResultSet<User> result = users.Get(1); 
if(result.OK)
    Console.WriteLine(user.ToString()); 
else
    Console.WriteLine("Failed to get user.."); 

Альтернатива A похожа по поведению на int.Parse(string, out value) и легко расширять и читать.Добавление большего количества объектов к выводу, когда успех кажется легким и читабельным.

Альтернатива B кажется немного более замысловатой в том, что в каждой строке больше кода.Но может быть расширен для включения другой информации в ResultSet, а также обратно объекта.Труднее ли вернуть более одного объекта или какие-либо идеи относительно обходных путей?

Считается ли уродливой / плохой практикой использование таких параметров?

Ответы [ 2 ]

2 голосов
/ 01 марта 2012

Как правило, Microsoft не рекомендует использовать out-параметры в открытых методах . Надлежащим подходом было бы создание исключения, если метод не может выполнить работу, указанную в его имени. В этом случае, если метод Get не может Получить запись данных, должно быть исключение. Если такая ситуация возникает очень часто, вы можете использовать Альтернативу B, чтобы немного улучшить производительность, в отличие от выдачи исключений каждый раз.
Что касается Альтернативы A, метод должен быть назван TryGet в этом случае, чтобы соответствовать соглашениям об именах FCL (TryParse, TryGetValue и т.

0 голосов
/ 01 марта 2012

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

Например, если ваши методы Get или TryGet выглядят так ...

public bool TryGet(int userId, out User user) {
    try {
        var conn = CreateDbConnection();
        var myUser = GetUser(userId, conn);
        user = myUser;
        return true;
    }
    catch {
        return false;
    }
}

... тогда у вас нет возможности узнать, что не удалось при получении пользователя.Может быть, не удалось создать соединение с БД, возможно, пользователь с указанным идентификатором не существует и т. Д.

Лучший способ может быть следующим:

public MyUser GetUser(int userId) {
    MyDbConnection conn;
    try {
        conn = CreateDbConnection();
    }
    catch (Exception ex) {
        throw new Exception("The DB connection could not be created.", ex);
    }
    MyUser myUser = GetUser(userId, conn);
    if (myUser == null)
        throw new Exception("No user exists with the ID '" + userId + "'.");
    return myUser;
}    

Таким образом, вы знаете, что не работаети у вас есть лучшее сообщение, чтобы войти дальше по цепочке.

...