참고 : 이것은 수정 된 것으로 보입니다 Roslyn
내 대답 작성할 때 문제는 발생 이 하나 의 연관성에 대해 이야기, 널 병합 연산자 .
알림과 마찬가지로, null-coalescing 연산자의 아이디어는 폼의 표현입니다.
x ?? y
먼저 평가 x
한 후 다음을 수행하십시오.
- 값이
x
이 null 인y
경우 평가되고 표현식의 최종 결과입니다 - 값이 경우
x
비 - 널이,y
되어 있지 평가와의 값x
의 컴파일 시간 형으로 전환 된 후, 다음의 식의 최종 결과y
필요하다면
이제 일반적으로 변환이 필요하지 않거나 널 입력 가능 유형에서 널 입력 불가능 유형으로 변환됩니다. 일반적으로 유형은 동일하거나 (예 :에서)로 변경 int?
됩니다 int
. 그러나, 당신은 할 수 있습니다 자신의 암시 적 변환 연산자를 만들고, 사람들은 필요한 경우 사용된다.
의 간단한 경우에는 x ?? y
이상한 행동을 보지 못했습니다. 그러나 (x ?? y) ?? z
나는 혼란스러운 행동을 보았습니다.
짧지 만 완전한 테스트 프로그램은 다음과 같습니다. 결과는 주석으로 표시됩니다.
using System;
public struct A
{
public static implicit operator B(A input)
{
Console.WriteLine("A to B");
return new B();
}
public static implicit operator C(A input)
{
Console.WriteLine("A to C");
return new C();
}
}
public struct B
{
public static implicit operator C(B input)
{
Console.WriteLine("B to C");
return new C();
}
}
public struct C {}
class Test
{
static void Main()
{
A? x = new A();
B? y = new B();
C? z = new C();
C zNotNull = new C();
Console.WriteLine("First case");
// This prints
// A to B
// A to B
// B to C
C? first = (x ?? y) ?? z;
Console.WriteLine("Second case");
// This prints
// A to B
// B to C
var tmp = x ?? y;
C? second = tmp ?? z;
Console.WriteLine("Third case");
// This prints
// A to B
// B to C
C? third = (x ?? y) ?? zNotNull;
}
}
우리는 세 개의 사용자 정의 값 유형, 그래서 A
, B
그리고 C
C와 B, C에 A, 및 A로부터 B 로의 전환이를,
두 번째 경우와 세 번째 경우를 모두 이해할 수 있지만 첫 번째 경우에 추가 A에서 B 로의 전환이 필요한 이유 는 무엇입니까? 특히, 나는 첫 번째 사례와 두 번째 사례는 실제로 같은 것으로 예상 입니다. 결국 표현식을 로컬 변수로 추출하는 것입니다.
무슨 일이 일어나고 있습니까? C # 컴파일러와 관련하여 "버그"를 울리는 것은 매우 주저하지만, 무슨 일이 일어나고 있는지에 대해 충격을 받았습니다 ...
편집 : 좋아, 여기에 구성 자의 답변 덕분에 무슨 일이 일어나고 있는지에 대한 초기 예가 있습니다. 편집 : 이제 샘플에는 두 개의 null 병합 연산자가 필요하지 않습니다 ...
using System;
public struct A
{
public static implicit operator int(A input)
{
Console.WriteLine("A to int");
return 10;
}
}
class Test
{
static A? Foo()
{
Console.WriteLine("Foo() called");
return new A();
}
static void Main()
{
int? y = 10;
int? result = Foo() ?? y;
}
}
이것의 결과는 다음과 같습니다.
Foo() called
Foo() called
A to int
Foo()
여기에서 두 번 호출 되는 사실은 나에게 놀랍습니다. 표현이 두 번 평가 되는 이유를 알 수 없습니다 .
C? first = ((B?)(((B?)x) ?? ((B?)y))) ?? ((C?)z);
. 당신은 얻을 것이다 :Internal Compiler Error: likely culprit is 'CODEGEN'
(("working value" ?? "user default") ?? "system default")