Логические операторы в C всегда оценивают к булевым значениям. В C интервал 1
представляет true
, и интервал 0
представляет false
. Это - причина, почему и выражения, "All" && 1
и "All" || 1
, оценивают к 1
. Они оба логически верны. Для разъяснения рассмотрите следующую программу.
#include <stdio.h>
int main() {
printf("%d\n", 20 && 10); // 1
printf("%d\n", 20 || 10); // 1
return 0;
}
В вышеупомянутой программе, выражения 20 && 10
и 20 || 10
все еще оценивают к [1 110] даже при том, что нет никакого 1
в тех выражениях. Это имеет смысл, потому что оба тех выражения логически верны. Следовательно, они оценивают к [1 112], который эквивалентен [1 113] в JavaScript.
, Если бы JavaScript вел себя, путь C сделал тогда выражения "All" && 10
и "All" || 10
, оценил бы к булеву значению true
. Однако это не способ, которым логические операторы ведут себя в JavaScript. Но это вовсе не значит то, что они - багги.
Значения в JavaScript имеют понятие правдоподобия и ошибочности. Например, значения true
, "All"
, 10
, [10, 20]
, { foo: 10 }
, и x => 2 * x
являются всем truthy. С другой стороны, значения false
, ""
, 0
, undefined
, и null
являются falsy.
логические операторы JavaScript не всегда оценивают к булевым значениям как C, делает. Вместо этого они оценивают к одному из их операндов. &&
оператор оценивает к его левому операнду, если это - falsy. Иначе это оценивает к правильному операнду. Точно так же ||
оператор оценивает к его левому операнду, если это - truthy. Иначе это оценивает к правильному операнду.
Теперь, значение "All"
является truthy. Следовательно, "All" && 1
оценивает к правильному операнду (т.е. 1
), тогда как "All" || 1
оценивает к левому операнду (т.е. "All"
). Заметьте, что и 1
и "All"
значения truthy, что означает, что они эквивалентны [1 137] (который представляет правдоподобие) в C.
Следовательно, нет. JavaScript не является багги.
как насчет
singleLoadControl.Visible =
PostingType == PostingTypes.Loads && !IsMultiPost;
singleTruckControl.Visible =
PostingType == PostingTypes.Trucks && !IsMultiPost;
multiTruckControl.Visible =
PostingType == PostingTypes.Loads && IsMultiPost;
multiLoadControl.Visible =
PostingType == PostingTypes.Trucks && IsMultiPost;
, если вы хотите, чтобы можно было сделать несколько видимые элементы управления (или добавить другие перечисляемые значения) украшают перечисление атрибутом [Flags] следующим образом:
[Flags]
public enum PostTyp { None=0, IsMultiPost = 1, Loads = 2, Trucks = 4 }
и изменяют код следующим образом:
singleLoadControl.Visible =
((PostingType & (PostTyp.Loads | ~PostTyp.MultiCast))
== PostingType );
singleTruckControl.Visible =
((PostingType & (PostTyp.Trucks | ~PostTyp.MultiCast))
== PostingType );
multiTruckControl.Visible =
((PostingType & (PostTyp.Loads | PostTyp.MultiCast))
== PostingType );
multiLoadControl.Visible =
((PostingType & (PostTyp.Trucks | PostTyp.MultiCast))
== PostingType );
А как насчет этого:
singleLoadControl.Visible = false;
singleTruckControl.Visible = false;
multiTruckControl.Visible = false;
multiLoadControl.Visible = false;
if (PostingType == PostingTypes.Loads && !IsMultiPost)
{
singleLoadControl.Visible = true;
}
else if (PostingType == PostingTypes.Trucks && !IsMultiPost)
{
singleTruckControl.Visible = true;
}
else if (PostingType == PostingTypes.Loads && IsMultiPost)
{
multiLoadControl.Visible = true;
}
else if (PostingType == PostingTypes.Trucks && IsMultiPost)
{
multiTruckControl.Visible = true;
}
Поскольку вы, похоже, используете перечисление, я бы порекомендовал переключатель с регистром по умолчанию, чтобы справиться с неизвестными значениями. Я считаю, что этот подход проясняет намерения, чем выполнение всех проверок в назначении.
switch (PostingType)
{
case PostingTypes.Loads:
singleLoadControl.Visible = !IsMultiPost;
multiTruckControl.Visible = IsMultiPost;
singleTruckControl.Visible = false;
multiTruckLoadControl.Visible = false;
break;
case PostingTypes.Trucks:
singleLoadControl.Visible = false;
multiTruckControl.Visible = false;
singleTruckControl.Visible = !IsMultiPost;
multiLoadControl.Visible = IsMultiPost;
break;
default:
throw InvalidOperationException("Unknown enumeration value.");
}
Если это было бы разумно в противном случае (например, если это уже специфичные для домена настраиваемые элементы управления), вы могли бы инкапсулировать логику внутри самих элементов управления ( Заменить Условное с полиморфизмом ). Возможно, создадим такой интерфейс:
Если вы ожидаете добавить много разных параметров, вы можете создать многомерный массив of objects
Arr[0][0] = singleLoadControl
Arr[0][1] = singleTruckControl
Arr[1][0] = multiLoadControl
Arr[1][1] = multiTruckControl
Это довольно страшно, но упрощает операторы if. Если вы так или иначе собираетесь иметь множество ссылок на элементы управления, я бы предпочел использовать представление на основе кода того, что это за нагрузки. Такой массив можно обернуть в класс, чтобы вы могли получить доступ к элементам, используя что-то вроде:
ControlClassInstance.single.truck
У вас будет такой код:
p1 = IsMultiPost ? ControlClassInstance.multi : ControlClassInstance.single
p2 = p1[PostingType] //(this call would mean adding an indexer)
Этот вид решения слишком сложен, если вы не ожидаете, что все будет усложняться. ... и тогда тоже может быть бедным.
singleLoadControl.Visible = false;
singleTruckControl.Visible = false;
multiTruckControl.Visible = false;
multiLoadControl.Visible = false;
singleLoadControl.Visible = (PostingType == PostingTypes.Loads && !IsMultiPost);
singleTruckControl.Visible = (PostingType == PostingTypes.Trucks && !IsMultiPost);
multiLoadControl.Visible = (PostingType == PostingTypes.Loads && IsMultiPost);
multiTruckControl.Visible = (PostingType == PostingTypes.Trucks && IsMultiPost);
private void ControlSelect()
{
if (PostingType == PostingTypes.Loads && !IsMultiPost)
{
singleLoadControl.Visible = true;
singleTruckControl.Visible = false;
multiTruckControl.Visible = false;
multiLoadControl.Visible = false;
return;
}
if (PostingType == PostingTypes.Trucks && !IsMultiPost)
{
singleLoadControl.Visible = false;
singleTruckControl.Visible = true;
multiTruckControl.Visible = false;
multiLoadControl.Visible = false;
return;
}
if (PostingType == PostingTypes.Loads && IsMultiPost)
{
singleLoadControl.Visible = false;
singleTruckControl.Visible = false;
multiTruckControl.Visible = false;
multiLoadControl.Visible = true;
return;
}
if (PostingType == PostingTypes.Trucks && IsMultiPost)
{
singleLoadControl.Visible = false;
singleTruckControl.Visible = false;
multiTruckControl.Visible = true;
multiLoadControl.Visible = false;
return;
}
}