Почему на "bool?" Нет отмененных операторов короткого замыкания?
Почему поддержка bool?
не поддерживается &&
и ||
? Они могли бы поднять операторы true
и false
, которые косвенно добавили бы поднятые &&
и ||
.
Операторы |
и &
уже сняты и реализуют правильную трехзначную логику. Но, конечно, они не имеют короткого замыкания, например ||
и &&
.
Вопрос в том, почему они решили не поднимать этих операторов при создании спецификации. Итак, "Это так, потому что спецификация говорит так" - это не ответ на "почему?".
При подъеме true
и false
, так что null
не является ни true
, ни false
:
public static bool operator true(bool? x)
{
return x.HasValue && x.Value
}
public static bool operator false(bool? x)
{
return x.HasValue && !x.Value
}
Это привело бы к тому, что &&
и ||
ведут себя так же, как их не закорачивающие копии. За исключением того, что false && anything
и true || anything
будут иметь короткое замыкание (false
и true
не являются константами времени компиляции в этих двух примерах).
Это будет очень похоже на пример DBBool на MSDN.
Я не вижу неожиданного или опасного поведения, возникающего при подъеме этих операторов. Я что-то пропустил?
Я прочитал другой вопрос SO об этом, но не нашел ни одного из ответов, удовлетворяющих.
Ответ Джеффа Йетса показывает хорошую причину того, почему подъем операторов true
/false
не является оптимальным, он не объясняет, почему подъем &&
и ||
напрямую является плохим. Поскольку подъем оператора - это магия компилятора, в специальных случаях Nullable<T>
ему не нужно следовать правилам перегрузки для нормальных типов и, таким образом, сможет предложить &&
/||
без подъема true
.
Ответы
Ответ 1
Что вы предлагаете создать два разных шаблона использования для типов с нулевым значением.
Рассмотрим следующий код:
bool? a = null;
// This doesn't currently compile but would with lifted true/false operators.
if (a)
{
}
// Whereas this provides a consistent use of nullable types.
if (a ?? false)
{
}
Для согласованности использования типов с нулевым значением имеет смысл не поднимать операторы true
и false
на bool
. Я не знаю, является ли это реальной причиной, почему это не было сделано, но это имеет смысл для меня.
Ответ 2
Поскольку вы показали, что подъем true
и false
технически возможен, есть только два возможных ответа на ваш вопрос (с "они" являются людьми, которые написали компилятор/спецификацию):
- Это ошибка в спецификации, т.е. они не думали об этом. (возможно, но я сомневаюсь в этом)
- Они думали, что подъем короткозамкнутых операторов потенциально подвержен ошибкам. Это может быть тот же способ рассуждения, что и почему С# полностью основан на классе (нет единственных функций, как в С++), или почему оператор, такой как
if (myNullVar) { ... }
(с myNullVar
, являющийся ссылкой), не работает в С# (но это делает в C/С++).
Я думаю, что всегда есть баланс между тем, чтобы сделать язык программирования более мощным и сделать его менее подверженным ошибкам.
Обновление: Просто для вас интересует, что официальная документация говорит:
Это недопустимо, поскольку неясно, что означает null в контексте условного.
Ответ 3
false && anything
совпадает с false
. Однако, если вы ожидаете, что false && anything
будет истинным, только если anything
- false, тогда !anything
- это то, что вы хотите.
Кроме того, true || anything
совпадает с true
.... И я не уверен, как вы могли бы вернуть его в любое состояние, так как не имеет смысла "возвращать что-то"!
... почему добавление дополнительного веса к условию, когда все это ясно и просто, как оно есть?
Я обычно не адепт из "потому что это так", но я не вижу преимущества добавления таких функций.