2011-01-27 2 views
35

myObj가 null이라고 가정합니다. 이것을 쓰는 것이 안전합니까? .NET에서 && 단락 안전에 의존하고 있습니까?

if(myObj != null && myObj.SomeString != null) 

나는 두 번째 부분이 실행되기 전에 & &이 false로 평가하기 때문에 일부 언어는 두 번째 표현식을 실행하지 않습니다 알고있다.

답변

56

예. C# &&||은 단락되어 있으므로 왼쪽에서 아직 결과를 확인하지 않은 경우에만 오른쪽을 평가합니다. 반면에 &| 연산자는 단락시키지 않고 항상 양쪽을 평가합니다.

사양은 말한다 :

&&|| 연산자는 조건부 논리 연산자라고합니다. 그들은 또한 "단락 회로 (shortcircuiting)"논리 연산자라고도합니다.
...
y 제외 x && yx & y 조작에 대응하는 동작은 xtrue
...
x && y(bool)x ? (bool)y : false으로 평가되는 동작 때만 평가된다. 즉, x이 먼저 평가되어 bool 유형으로 변환됩니다. 그런 다음 xtrue 일 경우 y이 계산되어 bool 유형으로 변환되며 이는 연산 결과가됩니다. 그렇지 않은 경우 작업 결과는 false입니다.

(C# 언어 사양 버전 4.0-7.12 조건부 논리 연산자) &&||

한 가지 흥미로운 특성은 그들이 bools에서 작동하지 않는 경우에도 단락가 있지만 때문이다 유형의 경우 사용자가 truefalse 연산자와 함께 & 또는 | 연산자를 오버로드했습니다.

동작 x && yT.false((T)x)T에서 선언 operator false의 호출이다 T.false((T)x) ? (T)x : T.&((T)x, y), 및 T.&((T)x, Y)로 평가된다 선택한 operator &의 호출이다. 또한 값 (T) x는 한 번만 평가해야합니다. 즉

, x 먼저 평가 x 확실히 false 경우 Toperator false가 결정 결과에 호출 형식으로 변환됩니다.
x이 분명히 false이면 연산 결과는 x에 대해 이전에 계산 된 값이 T으로 변환됩니다.
그렇지 않으면 x에 대해 이전에 계산 된 값에 T으로 변환 된 값과 y으로 변환 된 값으로 선택한 연산자 &이 호출되어 작업 결과가 생성됩니다.

(C# 언어 사양 버전 4.0 - 7.12.2 사용자 정의 조건부 논리 연산자)

+5

그 마지막 단락은 너무 * 흥미 롭습니다 ... 내 머리를 다쳤습니다.:) –

+1

그것은 복잡해 보입니다.하지만 그다지 어렵지는 않습니다. 왼쪽의'false' 연산자가'true'를 반환하고 대신 왼쪽을 반환하고, 그렇지 않으면 커스텀'&'연산자를 호출하면 오른쪽을 평가하지 않습니다. 그래서 이것은 bool의 짧은 회로 동작을 모방합니다. 이것의 전형적인 적용은 세번째 상태를 가질 수있는 확장 된'bool'입니다. 예를 들어'DBBol' 또는'bool? '과 비슷한 것을 구현할 수 있습니다. – CodesInChaos

14

예, C#은 논리적 단락을 사용합니다.

C# 및 일부 다른 .NET 언어가이 방식으로 작동하지만 CLR이 아닌 언어의 속성임을 유의하십시오.

+9

사실, VB.NET은'AndAlso'와'OrElse'을 사용할 때 이런 식으로 행동합니다.'And'와'Or'에는 * not *를 사용합니다. 사람들의 90 %가 항상 사용하는 것 같습니다. –

+1

@Adam, 감사합니다. – harpo

+1

이것은 또한 구현 세부 사항 (언제든지 변경 될 수 있음)뿐만 아니라 C# 사양 (이 점에서 변경되지 않음)의 일부임을 유의해야합니다. –

0

그것은 완벽하게 안전합니다. C#은 해당 언어 중 하나입니다.

+0

여기에서 단락 회로 평가를 사용하는 언어 중 하나 – Brad

+0

@Adam 질문에 "일부 언어를 알고 있습니다 ..." –

+0

@Ilya Kogan : 질문을 자세히 읽어야 함을 의미합니다.) –

2

확실한 C#에서는 첫 번째 피연산자가 false이고 두 번째 피연산자가 평가되지 않으면 안전합니다.

+1

"아름다운 사람들"중 하나였습니다. 아마도 누군가가 당신의 대답에 투표 할 것입니다. – Pedro

+0

당신의 대답은 정확하지만 CodesInChaos –

0

예, C# 및 대부분의 언어는 if에서 왼쪽에서 오른쪽으로 문장을 계산합니다.

전체를 계산, 그것이 null 인 경우 예외가 발생합니다 그런데 VB6 ...

+0

만큼 상세하지는 않습니다. 이것은 틀린 것은 아니지만 너무 많은 수준에서 오도하는 것입니다. (1) 중괄호 언어는이 작업을 수행하는 언어의 일부입니다. (2) 구문 분석하기 전에 입력을 반대로하면 광란입니다. (3) 파싱 방법에 관계없이, 짧은 - curcuiting은 런타임 의미론입니다. (4) VB에 관한 harpo의 대답을 참고하십시오 -''그리고''짧은 curcuit하지 않습니다,하지만''도하지 않습니다. (아마도 2 + 3은 런타임시 발생하는 무언가와 파싱을 혼동하기 때문에 ...) – delnan

+0

예, ment는 "계산합니다"구문을 편집합니다. –

4

코드는 안전합니다 - & & 및 || 둘 다 단락되어있다. 비 단락 연산자 & 또는 |을 사용하여 양쪽 끝을 평가할 수 있지만, 많은 프로덕션 코드에서이를 실제로 볼 수는 없습니다.

1

예 양쪽이 실행될 경우 광고가 널 예외 야기

if(strString != null && strString.Length > 0) 

이다.

흥미로운 측면 메모. 위의 예제는 IsNullorEmpty 메서드보다 훨씬 빠릅니다.

0

, &&|| 첫번째 조건 평가 즉, 단락 및 응답이 결정되면, 나머지는 무시된다.

VB.NET에서 AndAlsoOrElse도 단락되어 있습니다.

자바 스크립트에서 &&||도 단락되어 있습니다.

나는 VB.NET에서 추악한 빨간 머리가 된 단계 자식에 대해서도 언급합니다.

웹 개발을하고 있다면 자바 스크립트를 사용하기 때문에 자바 스크립트를 언급했습니다.