Introduction
- 기본적으로 값 형식은 항상 해당 타입에 맞는 값을 가져야 하고, null을 가질 수 없다.
값 형식
에null
값이 필요한 경우?
를 붙여null 허용 값 형식 (T?)
으로 선언할 수 있다.null 허용 값 형식
은 System.Nullable<T> 구조체의 인스턴스이며, 조건에 따라System.T
형식으로 돌아올 수 있다.
T? 선언 및 사용
아래와 같이
T?
형식을 선언 및 사용할 수 있다.int X = 1; double? Y = default; Console.WriteLine(X); // 1 Console.WriteLine(Y); // null
T? 형식 및 인스턴스 검사
아래와 같이
T?
형식 검사를 수행할 수 있다.// 형식 검사 if(Nullable.GetUnderlyingType(typeof(T?))) { // Processing... }
아래와 같이 형식 검사를 수행하면 안된다. 아래는 잘못된 두 가지 방법에 대한 MSDN 예제이다.
int? a = 17; Type typeOfA = a.GetType(); Console.WriteLine(typeOfA.FullName); // Output: // System.Int32
int? a = 14; if (a is int) { Console.WriteLine("int? instance is compatible with int"); } int b = 17; if (b is int?) { Console.WriteLine("int instance is compatible with int?"); } // Output: // int? instance is compatible with int // int instance is compatible with int?
T?
의 인스턴스 검사 방법은 아래와 같다.int? A = 1; if(A is int valueA) { // Processing... } int? B = 2; if(B.HasValue) { // Processing... } int? C = 3; if(C != null) { // Processing... }
T? -> T 형식 변환
아래와 같은 방법으로
T?
형식을T
형식으로 변환할 수 있다.int? A = 1; int B = A ?? -999; int? C = null; int D = C ?? -999; Console.WriteLine(B); // 1 Console.WriteLine(D); // -999;
int? A = 1; int B = A.GetValueOrDefault(); // 1 int? C = null; int D = C.GetValueOrDefault(); // 0
// 명시적 캐스팅 가능 int? A = 1; int B = (int)A; // null을 변환하려 하는 경우 exception 발생 A = null; B = (int)A; // System.InvalidOperationException: 'Nullable object must have a value.'
T? 연산
T?
연산은T
와 동일하게 지원된다.다만 연산자가 리프트 연산자로 적용되어
null
에 대한 규칙이 추가로 적용된다.int? A = 1; int? B = 5; int? C = null; int? D = null; Console.WriteLine(A + B); // 6 Console.WriteLine(A + C); // null Console.WriteLine(A > null); // False Console.WriteLine(A <= null); // False Console.WriteLine(C > D); // False Console.WriteLine(C == D); // True