Почему неправильно это встроенное, если?

Если есть следующее утверждение:

return this.revision.HasValue ? this.revision : throw new InvalidOperationException();

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

Есть ли способ исправить это утверждение или почему это не разрешено?

Спасибо.

EDIT: this.revision имеет значение int? и метод возвращает int.

EDIT 2: если у меня есть этот метод

public int Test()
{
    throw new Exception();
}

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


person Ignacio Soler Garcia    schedule 22.11.2013    source источник
comment
Каков тип возвращаемого значения вашего метода?   -  person Christos    schedule 22.11.2013
comment
Из msdn: либо типы first_expression и second_expression должны быть одинаковыми, либо должно существовать неявное преобразование одного типа в другой. msdn.microsoft.com/en-us/library /ty67wk28(v=vs.110).aspx   -  person Ric    schedule 22.11.2013
comment
предоставьте сообщение об ошибке (Visual Studio). на первый взгляд ревизия != исключение.   -  person mnemonic    schedule 22.11.2013
comment
Добавил запрошенную информацию, спасибо.   -  person Ignacio Soler Garcia    schedule 22.11.2013
comment
throw не является типом, а условный оператор не является if-else.   -  person Tim Schmelter    schedule 22.11.2013
comment
Я думаю, что комментарий Тима Шмельтера дает подсказку. ?: условный оператор, а не оператор if: ?: оператор: msdn.microsoft.com/en-us/library/vstudio/ty67wk28.aspx — инструкция if: msdn.microsoft.com/en-us/library/5011f09h(v=vs.90).aspx   -  person Kai Hartmann    schedule 22.11.2013
comment
Я не могу поверить, что люди тратят столько времени на этот вопрос. Это просто синтаксическая ошибка.   -  person Rui Jarimba    schedule 22.11.2013
comment
@KaiHartmann: спасибо, что указали на мою ошибку. Если вы напишите это как ответ, я приму это.   -  person Ignacio Soler Garcia    schedule 23.11.2013


Ответы (5)


Преобразование комментария в ответ:

Из MSDN:

Либо тип first_expression и second_expression должен быть одинаковым, либо должно существовать неявное преобразование одного типа в другой.

?: Оператор

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

person Ric    schedule 22.11.2013
comment
Опять же, я ожидал, что компилятор будет достаточно умен, чтобы понять, что в этом случае возвращаемое значение не имеет значения... Проверьте мое редактирование - person Ignacio Soler Garcia; 22.11.2013
comment
но он немного отличается от традиционного оператора if..else тем, что его типы должны совпадать или иметь возможность быть преобразованными для присваивания. - person Ric; 22.11.2013
comment
Я ожидал, что компьютер нарушит программу и прочитает мои мысли. Помогите, интернет. - person Gusdor; 22.11.2013
comment
@SoMoS: компилятор умен, но он должен следовать правилам, и одно правило состоит в том, что синтаксис должен быть допустимым. Если вы используете условный оператор, правила строгие. Если вам это не нравится, вы должны использовать if-else. - person Tim Schmelter; 22.11.2013
comment
@Ric: целое? не может быть преобразован в исключение, следовательно, ошибка в вашем коде Даже если его можно преобразовать в исключение, код будет недействительным, поскольку throw не является типом исключения, throw запрещен в условном операторе. - person Tim Schmelter; 22.11.2013
comment
Как внутр.? не может быть преобразовано в исключение -› неправильно, это вовсе не причина. Если бы вместо этого OP использовал исключение, это тоже не сработало бы. - person ken2k; 22.11.2013
comment
@ ken2k Просто указать на несоответствие типов - это все, к чему я стремился. Как бы вы это сформулировали? Также цитата из MSDN ясно показывает, что типы должны быть одинаковыми или должно существовать преобразование. - person Ric; 22.11.2013
comment
@Ric: для условного оператора требуется два выражения, и каждое выражение должно иметь один и тот же тип (или существует неявное преобразование). throw – это оператор не выражение. - person Tim Schmelter; 22.11.2013
comment
@Ric Это не несоответствие типов, просто throw не является выражением. - person ken2k; 22.11.2013

Я предполагаю, что проблема в том, что this.revision является типом, допускающим значение NULL, а InvalidOperationException() является SystemException. Вы не можете иметь два разных типа в операторе if, например:

return (a>b)? DateTime.Now : 2;

Пожалуйста, посмотрите здесь: http://msdn.microsoft.com/en-us/library/vstudio/ty67wk28.aspx

условие ? первое_выражение : второе_выражение;

Условие должно оцениваться как истинное или ложное. Если условие истинно, первое_выражение оценивается и становится результатом. Если условие ложно, вычисляется second_expression и становится результатом. Оценивается только одно из двух выражений.

Либо тип first_expression и second_expression должен быть одним и тем же, либо должно существовать неявное преобразование одного типа в другой.

person Christos    schedule 22.11.2013
comment
Я ожидал, что компилятор будет достаточно умен, чтобы понять, что в данном случае возвращаемое значение не имеет значения... - person Ignacio Soler Garcia; 22.11.2013
comment
@SoMoS тернарный оператор требует, чтобы типы были одинаковыми или неявно преобразуемыми msdn.microsoft.com/en-us/library/ty67wk28%28v=vs.110%29.aspx - person Gusdor; 22.11.2013

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

MSDN:

Если условие ложно, вычисляется second_expression и становится результатом.

person Ganesh Jadhav    schedule 22.11.2013

Это связано с тем, что второй операнд ?: должен быть выражением, а не оператором throw.

так что вы можете сделать это-

public static T ThrowException<T>()
{
    throw new Exception();
}

и использовать его в своем заявлении

return this.revision.HasValue ? this.revision :ThrowException<bool>();
person Microsoft DN    schedule 22.11.2013

Компилятор C# мог бы позволить это, и он мог бы делать гораздо больше вещей, чем сегодня. Проблема заключается в стоимости написания функции и последующей ее поддержки. См. сообщение в блоге Эрика Ганнерсона с описанием новой функции. процесс принятия решения.

person ya23    schedule 22.11.2013