물음표와 도트 연산자는 무엇입니까? C # 6.0의 의미는 무엇입니까?


359

VS2015 미리보기에서 C # 6.0을 ?.사용하면 다음과 같이 사용할 수 있는 새로운 연산자 가 있습니다.

public class A {
   string PropertyOfA { get; set; }
}

...

var a = new A();
var foo = "bar";
if(a?.PropertyOfA != foo) {
   //somecode
}

정확히 무엇을합니까?

답변:


499

그것은이다 널 (null) 조건 연산자. 기본적으로 다음을 의미합니다.

"첫 번째 피연산자를 평가합니다. null 인 경우 중지하고 결과는 null입니다. 그렇지 않으면 두 번째 피연산자를 평가하십시오 (첫 번째 피연산자의 구성원 액세스 권한으로)."

당신의 예에서, 포인트가있는 경우이다 a이고 null, 다음 a?.PropertyOfA으로 평가됩니다 null예외를 던지는 것이 아니라 - 그것은 그 비교합니다 null와 참조 foo(문자열의 사용 ==과부하)가 동일하지 않은 찾아 실행은 본문에 갈 것 if문 .

다시 말해, 다음과 같습니다 :

string bar = (a == null ? null : a.PropertyOfA);
if (bar != foo)
{
    ...
}

... 단 a한 번만 평가됩니다.

이렇게하면 표현식의 유형도 변경 될 수 있습니다. 예를 들어을 고려하십시오 FileInfo.Length. 이것은 type의 속성 long이지만 null 조건부 연산자와 함께 사용하면 type 식으로 끝납니다 long?.

FileInfo fi = ...; // fi could be null
long? length = fi?.Length; // If fi is null, length will be null

8
null 조건부 연산자 라고하지 않습니까?
SLaks

1
@ SLaks : "조건부 null"이라고 생각했지만 잘못되었을 수 있습니다. 마지막으로 Roslyn 언어 기능 문서를 확인했을 때 이름이 바뀌지 않았습니다. 어쩌면 소스가 여기있는 권한 일 것입니다-확인하십시오.
Jon Skeet

3
@ SLaks : 물론입니다. SyntaxKind 그것은 ... 둘 중 성가 시게하지 ConditionalAccessExpression 분명히입니다
존 소총

12
P는 : 전 이름 "엘비스"연산자 바람직
아메드 ilyas

3
기록을 위해이 연산자의 안전한 탐색, null 조건부, null 전파, 조건부 액세스, Elvis의 5 가지 이름을 보았습니다.
Gigi

81

계층 구조 및 / 또는 객체 매핑을 평탄화 할 때 매우 유용 할 수 있습니다. 대신에:

if (Model.Model2 == null
  || Model.Model2.Model3 == null
  || Model.Model2.Model3.Model4 == null
  || Model.Model2.Model3.Model4.Name == null)
{
  mapped.Name = "N/A"
}
else
{
  mapped.Name = Model.Model2.Model3.Model4.Name;
}

다음과 같이 작성할 수 있습니다 (위와 동일한 논리)

mapped.Name = Model.Model2?.Model3?.Model4?.Name ?? "N/A";

DotNetFiddle.Net 작업 예 .

합니다 ( ?? 또는 널 유착 연산자 댄 다르다 ? 또는 널 조건 연산자 ).

또한 Action을 사용하여 할당 연산자 외부에서 사용할 수도 있습니다. 대신에

Action<TValue> myAction = null;

if (myAction != null)
{
  myAction(TValue);
}

다음과 같이 단순화 할 수 있습니다.

myAction?.Invoke(TValue);

DotNetFiddle 예 :

시스템 사용;

public class Program
{
  public static void Main()
  {
    Action<string> consoleWrite = null;

    consoleWrite?.Invoke("Test 1");

    consoleWrite = (s) => Console.WriteLine(s);

    consoleWrite?.Invoke("Test 2");
  }
}

결과:

시험 2


27
사람들이 무엇을 찾도록 저장하려면 ?? is .. 널 병합 연산자이며 널이 아닌 경우 Name을 리턴하고 그렇지 않으면 "N / A"를 리턴합니다.
Steve

6
@Erik 필립스 난 당신이 추가 할 필요가 있다고 생각 || Model.Model2.Model3.Model4.Name == null 하는 경우가 그렇지 않은 경우에, 같은 논리를 가지고 Model.Model2.Model3.Model4.Name있다 null, mapped.Name남아있을 것입니다null
RazvanR

2
@ErikPhilips 같은 페이지에없는 것 같습니다. 경우 모두 사용자의 경우에 어떻게되는지보십시오 Model.Model2.Model3.Model4.Name입니다 null.
RazvanR

1
결과는 "N / A"입니다. 다시 첫 번째 주석을 읽으십시오. DotNetFiddle.Net 작업 예 .
Erik Philips

7
@ErikPhilips : 첫 번째 예제와 관련이 없으므로 첫 번째 주석과 관련이 없습니다. 이것에서 당신은 else-branch 로 뛰어 들어 있고 가지고 mapped.Name = Model.Model2.Model3.Model4.Name -> mapped.Name = null있고, 두번째 예제는 대신 할 mapped.Name = "N/A"것이다.
derM

3

이것은 C #에 상대적으로 새로운 방법이므로 메서드 체인에서 null 또는 null이 아닌 값 과 관련하여 함수를 쉽게 호출 할 수 있습니다 .

같은 것을 달성하는 오래된 방법은 다음과 같습니다.

var functionCaller = this.member;
if (functionCaller!= null)
    functionCaller.someFunction(var someParam);

이제는 다음과 같이 훨씬 쉬워졌습니다.

member?.someFunction(var someParam);

나는 당신이 여기를 읽을 것을 강력히 권장합니다 :

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operators

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.