2017-02-07 22 views
4

Сегодня я делаю еще один вызов Codegolf над на Codegolf StackExchange, и я пытался сделать это:C# Enum требует броска в тройной форме?

SomeEnum = SomeCondition ? 1 : 2; 

, но это говорит мне Cannot convert source type 'int' to target type 'SomeEnum', поэтому я попытался вместо этого:

SomeEnum = SomeCondition ? (SomeEnum)1 : (SomeEnum)2; 

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

+1

Если вы удалите «избыточный» листинг, действительно ли код компилируется? –

+0

У вас есть небольшой пример этого? Я попытался воспроизвести его, и я должен выполнить оба результата, или мой код не будет компилироваться. – Equalsk

+0

@Damien_The_Unbeliever Да, код все еще компилируется и отлично работает, когда вы делаете только одну сторону. Это выглядит запутанным! – Metoniem

ответ

6

Правила для условного оператора является (C# Spec 7.14):

• If x has type X and y has type Y then 
o If an implicit conversion (§6.1) exists from X to Y, but not from Y to X, then Y is the type of the conditional expression. 
o If an implicit conversion (§6.1) exists from Y to X, but not from X to Y, then X is the type of the conditional expression. 
o Otherwise, no expression type can be determined, and a compile-time error occurs. 

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

Итак, почему ваш код работает? Потому что в вашем фактическом коде первое значение - 0, а не 1. И таким образом мы получаем один случай, когда целое число может быть неявно преобразован в перечисление (C# Spec 6.1.3):

Неявное преобразование перечисление разрешает десятичной целочисленный литерал 0 должны быть преобразованы в любой enum-type и любым с нулевым типом, базовым типом которого является enum-type ...

+0

Спасибо большое за ваш ответ, я никогда не знал об этом, и я понятия не имел, что 0 повлияет на мой пример. Теперь я понимаю! :) – Metoniem

+2

Мораль истории - не публиковать псевдокод, опубликовать пример [минимальный, полный и проверяемый] (http://stackoverflow.com/help/mcve) ;-) – Equalsk

+0

@Equalsk Да, это было бы определенно предотвратил путаницу здесь. Я буду помнить об этом! – Metoniem

0

Чтобы связать результат троичного оператора SomeEnum, результат обоего ветвей (истинный и ложный), должен быть в состоянии быть отлиты неявно к SomeEnum, но нет не неявного оператора литой по умолчанию int, определенный для типа enum в C#. Если был неявный оператор, это будет действительный сценарий.

Надеюсь, это объяснит ситуацию.

+0

Тип возврата условного оператора основан исключительно на типах содержащихся в нем выражений. Это не так, как вы утверждаете, каким-то образом зависит от переменной результата (фактически, в большом числе случаев, когда используется как часть большего выражения, нет «переменной результата») –

+0

Thansk для исправления, я отредактировал мой ответ. –

0

компилируется без предупреждения:

SomeEnum SomeEnum = (true) ? (SomeEnum)1 : (SomeEnum)2; 

Но вы должны присвоить переменной ENUM значение перечисления:

SomeEnum SomeEnum = (true) ? SomeEnum.First : SomeEnum.Second; 

public enum SomeEnum : byte 
{ 
    First = 1, 
    Second = 2 
} 

Следующая должен не компиляции:

SomeEnum SomeEnum = (true) ? (SomeEnum)1 : 2; //THIS WON'T COMPILE! 

... если первое значение не равно 0:

SomeEnum SomeEnum = (true) ? 0 : 2; 
+0

Посмотрите на [мой код здесь] (http://codegolf.stackexchange.com/a/109377/65012), он компилируется нормально, пока он кажется почти идентичным тому, что вы сказали, не должен компилироваться. Я очень смущен. – Metoniem

+0

* Почти * идентичный не идентичный. Разница в том, что введенный вами код устанавливает значение 1 вместо 0. Большая разница, как указал другой ответ. Существует причина, по которой вы всегда должны предоставлять воспроизводимый образец вашей проблемы, когда задаете вопрос ... – mm8

3

Вы можете написать, как этот также

SomeEnum = (SomeEnum)(SomeCondition ? 1 : 2); 

SomeEnum левой стороны всегда ожидает результат как 'SomeEnum'. Поэтому нам нужно его преобразовать.

+0

Это действительно не путаный способ бросить действительно, я обязательно его использую, и я поддержал ваш ответ, но это действительно не отвечает на мой вопрос полностью! Спасибо anyways :) – Metoniem

 Смежные вопросы

  • Нет связанных вопросов^_^