Я немного озадачен этой небольшой причудой C#:
Учитывая переменные:
Boolean aBoolValue;
Byte aByteValue;
Следующие компиляции:
if (aBoolValue)
aByteValue = 1;
else
aByteValue = 0;
Но это не будет:
aByteValue = aBoolValue ? 1 : 0;
Ошибка говорит: "Не может неявно преобразовать тип 'интервал' в 'байт'".
И конечно, это чудовище скомпилирует:
aByteValue = aBoolValue ? (byte)1 : (byte)0;
Что продолжается здесь?
Править:
Использование VS2008, C# 3.5
Это довольно часто задаваемый вопрос.
В C # мы почти всегда рассуждаем изнутри наружу. Когда вы видите
x = y;
, мы выясняем, что такое тип x, каков тип y и является ли тип y совместимым по присваиванию с x. Но мы не используем тот факт, что мы знаем, что это за тип x, когда мы разрабатываем тип y.
Это потому, что может быть более одного x:
void M(int x) { }
void M(string x) { }
...
M(y); // y is assigned to either int x or string x depending on the type of y
Нам нужно , чтобы иметь возможность определить тип выражения , не зная, чему оно присваивается. Информация о типе передается из выражения, а не в выражение.
Чтобы определить тип условного выражения, мы определяем тип следствия и альтернативные выражения, выбираем более общий из двух типов, который становится типом условного выражения. Итак, в вашем примере тип условного выражения - «int», и он не является константой (если только выражение условия не является константой true или константой false). Поскольку это не константа, вы не можете присвоить его байту; компилятор исходит исключительно из типов, а не из значений, когда результат не является константой.
Исключением из всех этих правил являются лямбда-выражения, где информация о типе действительно перетекает из контекста в лямбда. Разобраться в этой логике было очень сложно.
Возможно, у меня нет для вас отличного ответа, но если вы сделаете это во многих местах, вы можете объявить:
private static readonly Byte valueZero = (byte)0;
private static readonly Byte valueOne = (byte)1;
и только эти переменные. Вы можете обойтись без использования const
, если он является локальным для проекта.
РЕДАКТИРОВАТЬ: использование только для чтения
не имело бы смысла - они никогда не должны изменяться.
Я использую VS 2005, и я могу воспроизвести его для логических и логических значений, но не для истинных значений
bool abool = true;
Boolean aboolean = true;
Byte by1 = (abool ? 1 : 2); //Cannot implicitly convert type 'int' to 'byte'
Byte by2 = (aboolean ? 1 : 2); //Cannot implicitly convert type 'int' to 'byte'
Byte by3 = (true ? 1 : 2); //Warning: unreachable code ;)
Самый простой способ обхода этой проблемы - это cast
Byte by1 = (Byte)(aboolean ? 1 : 2);
Итак, да, похоже, что тернарный оператор заставляет константы «фиксировать» свои типы как целые числа и отключать неявное преобразование типов, которое в противном случае вы бы получили от констант, которые вписываются в меньший тип.