Возврат кортежавместо того, чтобы бросить исключение ()? - PullRequest
4 голосов
/ 21 марта 2012

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

У меня есть два варианта оформления подписи метода:

1.Tuple

Tuple<bool, string> Foo()  
{  
    if(!DoHardWorkA()) return Tuple.New(false, "cannot do hardwork A");  
    if(!DoHardWorkB()) return Tuple.New(false, "cannot do hardwork B");  

    return Tuple.New(true, String.Empty);
}

2.Exception

void Foo()
{
    if(!DoHardWorkA()) throw new ProgramSpecificException("cannot do hardwork A");
    if(!DoHardWorkB()) throw new ProgramSpecificException("cannot do hardwork B");

    return Tuple.New(true, String.Empty);
}

Как DoHardWorkA (), так и DoHardWorkB () являются внешними методами, которые я не могу контролировать, и они возвращают true / false, указывая результат.

Логично, я думаю, что я должен пойти с вариантом 2, поскольку они действительно исключения; Но для согласованности я бы хотел воспользоваться вариантом 1.

Какой из них вы предпочитаете, почему?

Ответы [ 5 ]

3 голосов
/ 21 марта 2012

Лучше бросать исключение и обрабатывать его согласованно.

Если Foo не работает по любой другой причине, он также будет обработан.Предположим, что scenerio.

void UIMethod()
{
   Tuple<Result, Error> ret = Foo();
   if(ret.Error)
     MessageBox.Show(ret.Error);
}

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

Гораздо проще сделать это.

void UIMethod()
{
   try{  
       MethodBeforeFoo();
       var ret = Foo();
    }
   catch(Exception ex)
    {
       MessageBox.Show(ex.Message); 
    }

}
1 голос
/ 21 марта 2012

Если все, что вы делаете, - это вызываете эти внешние методы для выполнения какой-то работы, и этот метод, который вы пишете, является оболочкой для них, тогда зачем выкидывать исключение, «обрабатывать» проблему в вашем методе и продолжать, выбрасывая и обработка исключений много много раз дороже

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

. Обратите внимание, что если вы просто перехватываете исключение, а не раскручиваете стек, стоимость будет довольно минимальной.Это только дорого, когда вы раскручиваете стек, как ex.ToString() или ex.StackTrace

1 голос
/ 21 марта 2012

Это действительно зависит от ваших потребностей. Измените ваш код следующим образом, он также будет обрабатывать необработанные исключения.

   Tuple<bool, string> Foo()  
{  
try
{
    if(!DoHardWorkA()) return Tuple.New(false, "cannot do hardwork A");  
    if(!DoHardWorkB()) return Tuple.New(false, "cannot do hardwork B");  

    return Tuple.New(true, String.Empty);
}
catch
{
  return Tuple.New(false, "cannot do hardwork A"); 
}

}

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

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

(*) зависит от того, как используются исключения - если вы все время генерируете общее исключение, оно выиграет 't быть другим

Конечно, вы можете использовать целое число в кортеже, чтобы указать тип проблемы, но числовое значение для типа ошибки не так описательно, как тип исключения (опять же, если вы неиспользуя общий тип, такой как Exception).

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

То, что я однажды сделал, вернуло null в случае успеха или сообщение об ошибке в случае ошибки.Исключение было неуместным, так как возможен сбой, и другие разработчики любят запускать «Перерыв при возникновении исключений»

String Foo()  
{  
    if(!DoHardWorkA()) return "cannot do hardwork A";
    if(!DoHardWorkB()) return "cannot do hardwork B";

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