다음 코드가 주어집니다.
string someString = null;
switch (someString)
{
case string s:
Console.WriteLine("string s");
break;
case var o:
Console.WriteLine("var o");
break;
default:
Console.WriteLine("default");
break;
}
switch 문이 일치하는 이유는 무엇 case var o
입니까?
(효과적으로) 거짓으로 평가 되기 때문에 case string s
일치하지 않는 것은 내 이해입니다 . VS 코드에 대한 인텔리는 나에게 말한다 A는 뿐만 아니라. 이견있는 사람?s == null
(null as string) != null
o
string
유사 항목 : Null 검사가있는 C # 7 스위치 케이스
답변
명시 적 유형에 대해를 switch
사용 하는 패턴 일치 문 내 case
에서 문제의 값이 특정 유형인지 파생 된 유형인지 묻습니다. 정확히 동일합니다.is
switch (someString) {
case string s:
}
if (someString is string)
값 null
에 유형이 없으므로 위의 조건을 충족하지 않습니다. 정적 유형은 someString
두 예 모두에서 작동하지 않습니다.
var
패턴 일치하지만 유형은 와일드 카드 역할을하며 포함한 모든 값과 일치합니다 null
.
default
여기 의 경우는 데드 코드입니다. 는 case var o
null 또는 null이 아닌 모든 값과 일치합니다. 기본이 아닌 경우는 항상 기본 사례보다 우선하므로 default
절대 적중되지 않습니다. IL을 보면 방출되지 않는 것을 볼 수 있습니다.
언뜻보기에 이것이 경고없이 컴파일된다는 것이 이상하게 보일 수 있습니다 (확실히 나를 버렸습니다). 그러나 이것은 1.0으로 돌아가는 C # 동작과 일치합니다. 컴파일러는 default
절대 적중되지 않는다는 것을 사소하게 증명할 수있는 경우에도 케이스를 허용 합니다. 다음을 예로 고려하십시오.
bool b = ...;
switch (b) {
case true: ...
case false: ...
default: ...
}
여기서는 default
절대 히트 bool
하지 않습니다 (1 또는 0이 아닌 값이있는 경우에도 ). 그러나 C #은 1.0부터 경고없이 이것을 허용했습니다. 패턴 매칭은 여기서이 동작과 일치합니다.
답변
여기에 여러 개의 트위터 댓글을 모으고 있습니다. 이것은 실제로 저에게 새로운 것이며, jaredpar가보다 포괄적 인 답변으로 뛰어 들기를 바라고 있습니다. 내가 이해하는 짧은 버전 :
case string s:
귀하의 경우에 실패한 if(someString is string) { s = (string)someString; ...
또는 if((s = (someString as string)) != null) { ... }
– null
테스트 를 포함하는 것으로 해석됩니다 . 거꾸로:
case var o:
여기서 컴파일러 결의 o
로 string
단순히 o = (string)someString; ...
– 어떤 null
시험 에도 불구하고 단지 유형을 제공하는 컴파일러로, 표면에 비슷 사실.
드디어:
default:
위의 경우가 모든 것을 포착하기 때문에 여기에 도달 할 수 없습니다 . 도달 할 수없는 코드 경고를 표시하지 않았다는 점에서 컴파일러 버그 일 수 있습니다.
나는 이것이 매우 미묘하고 미묘하며 혼란 스럽다는 데 동의합니다 . 그러나 분명히 case var o
시나리오는 널 전파 ( o?.Length ?? 0
등) 와 함께 사용됩니다 . 나는 이것이 와 사이에서 매우 다르게 작동한다는 것이 이상하다는 데 동의 하지만 현재 컴파일러가하는 일입니다.var o
string s
답변
정적 (컴파일 타임) 유형이 아니라 동적 (런타임) 유형에서 case <Type>
일치 하기 때문 입니다. 동적 유형이 없으므로 . 그냥 폴백입니다.null
string
var
(짧은 답변을 좋아하기 때문에 게시합니다.)