Каково Ваше мнение о бросок() метод?


В последнее время я, кажется, бегите в очень часто ситуации, когда я хочу написать что-то вроде следующего:

var x =
    condition1 ? value1 :
    condition2 ? value2 :
    condition3 ? value3 :
    condition4 ? value4 :
    throw new InvalidOperationException();

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

Конечно, выше строить не компилируется, потому что бросить это утверждение, а не выражение. Поэтому я хотела бы написать метод, который делает именно это:

/// <summary>Throws the specified exception.</summary>
/// <typeparam name="TResult">The type to return.</typeparam>
/// <param name="exception">The exception to throw.</param>
/// <returns>This method never returns a value. It always throws.</returns>
public static TResult Throw<TResult>(Exception exception)
{
    throw exception;
}

[...]

var x =
    condition1 ? value1 :
    condition2 ? value2 :
    condition3 ? value3 :
    condition4 ? value4 :
    Ut.Throw<MyType>(new InvalidOperationException());

Существуют ли какие-либо проблемы с этим подходом, что я не вижу?



1270
14
задан 10 апреля 2011 в 04:04 Источник Поделиться
Комментарии
5 ответов

Если это заставляет вас чувствовать себя лучше, библиотеку mscorlib и системы сборки оба имеют внутренние ThrowHelper классов нет ничего, кроме методов которого только заявление кинуть, как это:

internal static void ThrowKeyNotFoundException()
{
throw new KeyNotFoundException();
}

Сейчас я не собираюсь сказать, что это хорошая идея, но, конечно, госпожа имеет веские основания для этого, верно?

8
ответ дан 11 апреля 2011 в 05:04 Источник Поделиться

Я бы избежать с помощью такого заявления. Это не правильное место для этого строительства внутри ?: операторы и я не вижу существенных преимуществ в его использовании. Я бы рассмотреть возможность использования следующих вариантов:

1)

Type variable;
if (condition1) variable = value1;
else if (condition2) variable = value2;
...
else throw new InvalidOperationException();

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

2) Также, если ваш значение1, значение2, и т. д. не может быть нулем, тогда я хотел бы рассмотреть с помощью этого:

var variable = 
condition1 ? value1 :
condition2 ? value2 :
condition3 ? value3 :
condition4 ? value4 :
null;
if (variable == null) throw new InvalidOperationException();

С. П.: Конечно, я не могу быть уверен, не зная контекста, но если вам приходится часто писать такие заявления, то это уже вроде бы неправильно для меня, может быть, что-то может быть изменено на более высокий уровень?

18
ответ дан 10 апреля 2011 в 04:04 Источник Поделиться

Одна проблема с этим подходом заключается в трассировке стека населения.

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

Тот факт, что метод универсален СПИДа в насыщении трассировку стека с неактуальной информации.

8
ответ дан 10 апреля 2011 в 04:04 Источник Поделиться

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

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

Если условия проверки могут с легкостью отнести к различным государствам или конкретные реализации, советую редизайн.

Если нет никакой "логической" способ разделения различных назначений, я бы предпочел Snowbear решение с нулевой чек. Тем не менее, я вижу выгоду вашего решения, и найти его достаточно ясно.

7
ответ дан 11 апреля 2011 в 03:04 Источник Поделиться

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

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

Вот пример того, что становится менее элегантным без броска:

mylist.Add(new Item
{
Prop1 = int.Parse(input1),
Prop2 = input2 == "stuff" ? true : input2 == "notstuff" ? false : Ut.Throw(),
});

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

4
ответ дан 10 апреля 2011 в 05:04 Источник Поделиться