C# 10 - (3) 개선된 변수 초기화 판정
C#의 경우, 초기화를 하지 않은 변수를 사용하려고 하면,
void DoWork()
{
int i;
// 컴파일 오류 발생
// error CS0165: Use of unassigned local variable 'i'
Console.WriteLine(i);
}
CS0165 컴파일 오류가 발생합니다. 문제는, 이후 다양한 문법 확장이 일어나면서 초기화를 하지 않았다는 판정이 잘 이뤄지지 않는다는 점입니다. 가령, 아래의 이슈에서도 나오지만,
[Question] Why the output is CS0165 when using a is Constant pattern. #45582
; https://github.com/dotnet/roslyn/issues/45582
다음과 같은 코드의 경우,
DoWork();
void IfCondition()
{
var he = new Person("Anders");
if (he is Person person)
{
return;
}
Console.WriteLine(person);
Console.WriteLine();
}
정상적으로 컴파일이 되는 반면, if 문에 비교 연산자를 다음과 같이 추가하면,
if (he is Person person == false)
"Console.WriteLine(person);" 코드에서 CS0165 컴파일 오류가 발생하면서 person 변수가 초기화되지 않았다는 판정 오류가 발생합니다.
또 다른 판정 오류를 보면, 원래는 다음과 같이 코딩을 하면 value 값의 사용이 허용되지만,
// Null-conditional operator and CS0165 #45776
// ; https://github.com/dotnet/roslyn/issues/45776
void IfNotNullAndTryGet()
{
var he = new Person("Anders");
if (he != null && he.Attr.TryGetValue("key", out var value) == true)
{
value.ToString();
}
}
이렇게 null 조건 연산자(Null-conditional operator)를 함께 사용해 축약하면,
void IfNotNullAndTryGet()
{
var he = new Person("Anders");
// 또는 he.Attr?.TryGetValue로 호출하거나,
if (he?.Attr.TryGetValue("key", out var value) == true)
{
value.ToString(); // value에 대해 CS0165 오류
}
}
value 변수가 초기화되지 않았다는 컴파일 오류가 발생합니다. 이렇게 조합되는 여러 가지 상황에서 초기화 변수 여부를 정상적으로 판정하지 못하는 것을 C# 10에서 개선했다고 합니다.
(
첨부 파일은 이 글의 예제 코드를 포함합니다.)
재미있게도, 일단 문서상으로는 C# 10에서 개선했다고 하지만 실제로 해보면 C# 10과 무관하게 Visual Studio 버전에 따라 컴파일 여부가 결정됩니다. 실제로 위의 코드(첨부 파일을 다운로드해 압축을 풀은 프로젝트)를 Visual Studio 2019 이하 버전에서 실행하면 C# 버전 지정에 상관없이 CS0165 컴파일 오류가 발생하지만, Visual Studio 2022 Preview 3.0부터 테스트를 하면 C# 버전에 상관없이 잘 컴파일이 됩니다.
이걸 어떻게 설명해야 할지 모르겠군요. ^^
C# 10 - (1) 구조체를 생성하는 record struct (공식 문서, Static Abstract Members In Interfaces C# 10 Preview)
; https://www.sysnet.pe.kr/2/0/12790
C# 10 - (2) 전역 네임스페이스 선언 (공식 문서, Global Using Directive)
; https://www.sysnet.pe.kr/2/0/12792
C# 10 - (3) 개선된 변수 초기화 판정 (공식 문서, Improved Definite Assignment)
; https://www.sysnet.pe.kr/2/0/12793
C# 10 - (4) 상수 문자열에 포맷 식 사용 가능 (공식 문서, Constant Interpolated Strings)
; https://www.sysnet.pe.kr/2/0/12796
C# 10 - (5) 속성 패턴의 개선 (공식 문서, Extended property patterns)
; https://www.sysnet.pe.kr/2/0/12799
C# 10 - (6) record class 타입의 ToString 메서드를 sealed 처리 허용 (공식 문서, Sealed record ToString)
; https://www.sysnet.pe.kr/2/0/12801
C# 10 - (7) Source Generator V2 APIs (Source Generator V2 APIs)
; https://www.sysnet.pe.kr/2/0/12804
C# 10 - (8) 분해 구문에서 기존 변수의 재사용 가능 (공식 문서, Mix declarations and variables in deconstruction)
; https://www.sysnet.pe.kr/2/0/12805
C# 10 - (9) 비동기 메서드가 사용할 AsyncMethodBuilder 선택 가능 (공식 문서, Async method builder override);
; https://www.sysnet.pe.kr/2/0/12807
C# 10 - (10) 개선된 #line 지시자 (공식 문서, Enhanced #line directive)
; https://www.sysnet.pe.kr/2/0/12812
C# 10 - (11) Lambda 개선 (공식 문서 1, 공식 문서 2, Lambda improvements)
; https://www.sysnet.pe.kr/2/0/12813
C# 10 - (12) 문자열 보간 성능 개선 (공식 문서, Interpolated string improvements)
; https://www.sysnet.pe.kr/2/0/12826
C# 10 - (13) 단일 파일 내에 적용되는 namespace 선언 (공식 문서, File-scoped namespace)
; https://www.sysnet.pe.kr/2/0/12828
C# 10 - (14) 구조체 타입에 기본 생성자 정의 가능 (공식 문서, Parameterless struct constructors)
; https://www.sysnet.pe.kr/2/0/12829
C# 10 - (15) CallerArgumentExpression 특성 추가 (공식 문서, Caller expression attribute)
; https://www.sysnet.pe.kr/2/0/12835
Language Feature Status
; https://github.com/dotnet/roslyn/blob/main/docs/Language%20Feature%20Status.md
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]