В C# есть 2 вида операторов:
- операторы Сочетания:
&&
, ||
- Битовые операторы:
&
, |
В контекстные операторы пропускают остальную часть выражения как только результат операции ясно, это означает, что:
для И: он оценивается до false
, если какая-либо часть выражения оценивается как false
для OR: он вычисляет true
, если какая-либо часть выражения вычисляется в true
В отличии от этого поведения, битовых операторов всегда оценивать все выражение. В большинстве случаев операторы ярлыков делают красиво и могут сэкономить время, если сложные выражения оцениваются очень часто (например, внутри большого цикла).
Но иногда вы должны использовать побитовые операторы , особенно если вызываемые функции имеют побочные эффекты (они также используются для двоичных побитовых вычислений, но это не обсуждается здесь).
Пример:
int countEven = 0;
int countOdd = 0;
bool isEven(int x)
{
countEven++;
return (x % 1)==0;
}
bool isOdd(int x)
{
countOdd++;
return (x % 1) != 0;
}
Теперь, если у вас есть
var a=5;
var expression = (a==4) && (isEven(2) || isOdd(1));
Console.WriteLine($"Expression result: {expression}");
Console.WriteLine($"Even calls: {countEven}, Odd calls: {countEven} ");
Вы получите 0
для countEven
, а также для countOdd
, поскольку функции isEven(2)
и isOdd(1)
никогда не называются.
Изменить что:
var expression = (a==4) & (isEven(2) | isOdd(1));
и функции будут вызываться, так countEven
и CountOdd
в настоящее время увеличивается.
Конечно, побочных эффектов (как показано выше) следует избегать, но я надеюсь, что разница сейчас понятна.
* Шарфы были рядом * Ни один из этих средств не был близок? Непонятно, что вы на самом деле хотите здесь. – Liam
'! (A && b)' эквивалентно '! A || ! b' –