Почему на "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.... И я не уверен, как вы могли бы вернуть его в любое состояние, так как не имеет смысла "возвращать что-то"!

... почему добавление дополнительного веса к условию, когда все это ясно и просто, как оно есть?

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