Почему на `bool? Нет поднятых операторов короткого замыкания? - PullRequest
18 голосов
/ 05 марта 2011

Почему 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.

Ответы [ 3 ]

4 голосов
/ 05 марта 2011

То, что вы предлагаете, создаст два разных шаблона использования для типов, допускающих обнуляемость.

Рассмотрим следующий код:

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. Я не знаю, является ли это реальной причиной, почему это не было сделано, но для меня это имеет смысл.

4 голосов
/ 13 июня 2011

Поскольку вы показали, что поднять true и false технически возможно, есть только два возможных ответа на ваш вопрос (с "они" - люди, написавшие компилятор / спецификацию):

  1. Это ошибка в спецификации, т.е. они не думали об этом. (возможно, но я сомневаюсь в этом)
  2. Они думали, что снятие короткозамкнутых операторов потенциально подвержено ошибкам. Это может быть такой же способ рассуждения, как то, почему C # полностью основан на классе (нет единственных функций, как в C ++) или почему оператор типа if (myNullVar) { ... }myNullVar является ссылкой) не работает в C # (но он работает в C / C ++).

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

Обновление: Только для вашего интереса, это то, что официальная документация гласит:

Это недопустимо, потому что неясно, что означает нуль в контексте условного.

0 голосов
/ 05 марта 2011

false && anything совпадает с false. Однако, если вы ожидаете, что false && anything будет истинным, только если anything будет ложным, тогда !anything - это то, что вам нужно.

Также true || anything совпадает с true. ... И я не уверен, как вы могли бы вернуть false при любых условиях, так как не имеет смысла, чтобы "то или иное" ничего не возвращало!

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

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

...