C# 14 - (8) null 조건부 연산자 개선 - 대입문에도 사용 가능
이번 구문도 간단하게 살펴볼 수 있군요. ^^
[Proposal]: Null conditional assignment #8677
; https://github.com/dotnet/csharplang/issues/8677
Null-conditional assignment
; https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-14#null-conditional-assignment
C# 6부터 제공하던 null 조건부 연산자(?.)를 혹시 기억하시나요? ^^ 이 문법을 이용하면 굳이 null 체크를 하지 않아도 멤버에 접근할 수 있었는데요,
internal class Program
{
static void Main(string[] args)
{
{
Person? p = null;
FillName(p);
PrintName(p); // null이므로 아무것도 출력되지 않음
}
{
Person p = new Person();
FillName(p);
PrintName(p); // 출력: "MyClass: 홍길동"
}
}
static void FillName(Person? p)
{
p?.SetName("홍길동");
// 위의 코드는 다음과 같이 펼쳐집니다.
// if (p != null)
// {
// p.SetName("홍길동");
// }
}
static void PrintName(Person? p)
{
Console.WriteLine(p?.Name);
// 또는 필드 접근도 가능
// Console.WriteLine(p?.name);
// 위의 코드는 다음과 같이 펼쳐집니다.
// string? text = null;
// if (p != null)
// {
// text = p.Name; // 또는 p.name;
// }
// Console.WriteLine(text);
}
}
class Person
{
public string name = string.Empty;
public string Name
{
get => name;
set => name = value;
}
public void SetName(string name)
{
this.name = name;
}
public override string ToString()
{
return $"MyClass: {Name}";
}
}
그런데, 여기에는 특별한 제약이 하나 있었습니다. 위에서 보듯이 메서드 호출이나 프로퍼티의 getter, 필드의 읽기 접근은 가능한 반면, 프로퍼티의 setter 호출 또는 필드에 값을 할당하는 것은 불가능하다는 점입니다.
static void FillName(Person? p)
{
p?.SetName("Doe"); // 정상 동작
// C# 13까지 컴파일 오류
p?.Name = "Doe"; // 컴파일 오류 (속성의 setter는 null 조건부 연산자를 사용할 수 없음)
p?.name = "Doe"; // 컴파일 오류 (필드의 할당은 null 조건부 연산자를 사용할 수 없음)
}
왜 이런 제약이 있었는지는 알 수 없지만, C# 14부터는 null 조건부 할당(null conditional assignment)이라는 새로운 평가 방식이 도입되면서 저 2개의 제약이 사라졌습니다.
static void FillName(Person? p)
{
p?.SetName("Doe");
// C# 14부터 컴파일 가능
p?.Name = "Doe"; // 속성 대입에도 널 조건부 연산자 사용 가능
p?.name = "Doe"; // 필드 대입에도 널 조건부 연산자 사용 가능
}
어찌 보면, 저런 제약을 한 번도 경험해 본 적이 없는 분이라면 이걸 신규 기능이라고 생각하지 않고 널 조건부 연산자라는 본연의 뜻 그대로 기억해도 무방할 듯합니다. ^^
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]