в C # что означает «bool = bool! = true»? - PullRequest
17 голосов
/ 06 марта 2012

В поисках какой-то помощи у меня возникла проблема:

p.Enabled = p.Enabled != true;

Что именно это значит? Я никогда не видел этого раньше,

Примечание: предыдущая строка была var p = this.PageRepository.GetPage(id);

Ответы [ 10 ]

33 голосов
/ 06 марта 2012

Когда p.Enabled является нормальным bool, как правило, включены свойства Enabled,

p.Enabled = p.Enabled != true;

совпадает с

p.Enabled = ! p.Enabled;

другими словами: оно переворачивает или переключает p.Enabled.

Теперь, когда Enabled является bool?, сокращением для Nullable<bool>, результаты отличаются:

! ((bool?) null)           -> null
((bool?) null) != true     -> true 

Таким образом, p.Enabled = p.Enabled != true установит true, когда старое значение было false или null.

32 голосов
/ 06 марта 2012

Это неловко написанный тумблер. Каждый вызов переключает состояние с истинного на ложное. Я бы написал это:

p.Enabled = !p.Enabled;

Редактировать - я полагаю, что должен сказать, неловко написано только на мой взгляд.

19 голосов
/ 06 марта 2012

Так много ответов ... Я просто хочу разбить это немного подробнее:

p.Enabled = p.Enabled != true;

Семантически эквивалентно:

var IN = p.Enabled;
var OUT = IN != true;
p.Enabled = OUT;

Итак:

p.Enabled -> IN     IN != true      OUT -> p.Enabled
---------------     -------------   ----------------
true                true  != true   false
false               false != true   true
(if nullable) null  null  != true   true

Таким образом, из таблицы Truth видно, что это тот же *, что и логический оператор not (!) и может быть переписан как:

p.Enabled = !p.Enabled;

(Я полагаю, что большинство [опытных] программистов предпочитают эту последнюю форму, поскольку это довольно распространенная идиома.)

Удачного кодирования.


* Обратите внимание на добавление null в качестве третьего состояния ввода в случае типов bool? (он же Nullable<bool>). (Спасибо, Томас Мэйфилд; -)

10 голосов
/ 06 марта 2012

Это то же самое, что и p.Enabled = !p.Enabled;, противоположное p.Enabled.

9 голосов
/ 06 марта 2012

Тест p.Enabled != true оценивается. Результат этого (который является логическим) присваивается p.Enabled. Таким образом, если p.Enabled равно true, тогда p.Enabled будет установлено в значение false. Еще один способ сказать, что это p.Enabled = !p.Enabled. То есть оно в основном инвертирует значение p.Enabled.

8 голосов
/ 06 марта 2012

, если p.Enabled - это обычное bool, это эквивалентно p.Enabled = !p.Enabled. то есть переключается p.Enabled.

Но если p.Enabled является недействительным булом, он будет отображать null и false на true, а также true на false. Но я бы предпочел написать p.Enabled = !(p.Enabled ?? true) в этом случае.

Если p.Enabled - это пользовательский тип с перегруженными операторами неявного преобразования, может произойти все что угодно.

4 голосов
/ 06 марта 2012

По сути, это перевернет значение p.Enabled. Таким образом, если это правда, то p.Enabled != true оценивается как ложное, и тогда этому ложному значению присваивается p.Enabled = false. И было бы работать наоборот, если бы p.Enabled были ложными.

Это могло бы иметь больше смысла, если бы оно было написано так:

p.Enabled = !(p.Enabled);
3 голосов
/ 06 марта 2012

Строка оценивает p.Enabled != true, что равно false, если p.Enabled равно true, и true, если p.Enabled равно false. Другими словами, очень неловкий способ написания

p.Enabled = !p.Enabled
3 голосов
/ 06 марта 2012

Думайте об этом так:

p.Enabled = (p.Enabled != true);

Теперь (p.Enabled != true) оценивается как bool, который затем может быть присвоен другой переменной bool.

1 голос
/ 06 марта 2012

Используйте эту функцию:

bool cond = (p.Enabled != true);
if (cond == true) 
{
  p.Enabled = cond; // = true
}
else
{
  p.Enabled = cond; // = false
}
...