안녕하세요. BlockDMask 입니다. 오늘은 C#에 존재하는 특별한 타입인 Nullable Type에 대해서 이야기 해보려합니다.
다들 C# 코드를 보다보면 "int 물음표"(=int?) 타입을 가끔씩 보시지 않았나요?
아니, int 타입이면 int 만 쓸것이지 뒤에 물음표는 뭐지? 하시는 분들이 있을 것 입니다.
C#에서는 Null을 가질 수 없는 타입들에게 특별히 Null을 가질 수 있게 하는 Nullable Type 이라는 개념을 도입했습니다.
(java에서도 비슷한게 있다는걸 들었는데.. java는 공부를 안해서..모르겠네요)
> 목차
1. Nullable Type 이란?
2. Nullable Type의 선언 방법, 속성과 메서드, 사용법 및 주의점
3. 다양한 Nullable Type 예제
4. Nullable 다시한번 총정리
그럼 이제 시작해보겠습니다.
1. Nullable Type 이란?
- C# Nullable Type 이란 Null 을 가질 수 없는 데이터 타입을 Null을 가질 수 있는 타입으로 만든 새로운 타입입니다.
- 대표적으로 값 타입(value type)들이 Null을 가질 수 없는데요. int, 구조체, double, bool 등의 데이터 타입은 값이 없는 상태(NULL)이 불가능한 데이터 타입들 입니다.
(클래스와 같은 reference type(=참조 타입)은 이미 Null 체크가 가능하기 때문에 따로 Nullable Type으로 만들지 않아도 됩니다.)
- int와 같은 값 타입에 대해서 "값이 없다"를 표현하기 위해 Nullable Type이 개발 되었다 라고 생각하시면 좋을듯 합니다.
- 우리는 int를 nullable int type으로 변경함으로서 값이 할당 되었는지 아닌지(null) 확인 할 수 있게 되었습니다.
2. Nullable Type의 선언 방법, 속성과 메서드, 사용법, 주의점
▶ 선언 방법
아래 두가지 방법으로 선언이 가능합니다.
개인적으로는 "데이터 타입 + ?" 방법이 더 보기 편하다고 생각이 듭니다.
Nullable<T> 변수명
T? 변수명
- 선언 예시
Nullable<int> num;
int? num;
▶ 속성과 메서드
1. HasValue 속성
값이 있는 경우 : true
값이 없는 경우(Null) : false
2. Value 속성
값이 있는 경우 : 할당된 값
값이 없는 경우(null) : 예외(Exception) 발생
3. GetValueOrDefault() 메서드
값이 있는 경우 : 할당된 값 반환
값이 없는 경우(Null) : 기존 타입의 default 값 반환
▶ 사용법
Nullable<int> a; // int? a;
a = null;
Console.WriteLine(a); // null이 나옵니다.
Console.WriteLine(a.HasValue); // 할당된 값이 없으므로 false
Console.WriteLine(a.Value); // 할당된 값이 없으므로 예외
Console.WriteLine(a.GetValueOrDefault()); // 할당된 값이 없으므로 int 타입의 default 값인 0 이 반환됩니다.
int? b; // Nullable<int> b;
b = 10;
Console.WriteLine(b); // 10이 나옵니다.
Console.WriteLine(b.HasValue); // 할당된 값이 있으므로 true
Console.WriteLine(b.Value); // 할당된 값이 있으므로 10
Console.WriteLine(b.GetValueOrDefault()); // 할당된 값이 있으므로 10이 반환됩니다.
▶ 주의점
- Nullable 중복 불가능
Nullable<Nullbale<int>> num; //불가능
- Value를 접근할때는 HasValue로 체크 한 후에 접근하기.
위에 예시에서 보셨겠지만 값이 존재하지 않는 Null인 경우 Value에 바로 접근하게 되면 예외가 발생하며 프로세스가 죽을 위험이 있습니다.
그렇기 때문에 HasValue로 값이 존재하는지 체크 한 후 에 Value에 안전하게 접근하는 방법을 추천드립니다.
- int, int?는 엄연히 다른 타입이므로 명시적 형 변환이 필요합니다.
3. Nullable Type 예제
▶int? 예제 1번 (메서드와 속성의 사용법)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | static void Main(string[] args) { Nullable<int> a; a = null; Console.WriteLine("Nullable<int> a : Null 일 때"); Console.WriteLine("a : {0}", a); Console.WriteLine("a.HasValue : {0} ", a.HasValue); //Console.WriteLine("a.Value : {0} ", a.Value); // 할당된 값이 없으므로 예외 Console.WriteLine("a.GetValueOrDefault() : {0} ", a.GetValueOrDefault()); Console.WriteLine(); a = 10; Console.WriteLine("Nullable<int> a : 10 일 때"); Console.WriteLine("a : {0}", a); Console.WriteLine("a.HasValue : {0} ", a.HasValue); Console.WriteLine("a.Value : {0} ", a.Value); Console.WriteLine("a.GetValueOrDefault() : {0} ", a.GetValueOrDefault()); } | cs |
▷1번 결과
▶Nullable Type 예제 2번(실제 프로그램을 만들때 사용하는 방법)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | static void Main(string[] args) { int? a = null; // or 22; if (a.HasValue) //HasValue로 값체크 먼저 수행 { //Null이 아닌 값이 들어있다. Console.WriteLine("a is not Null"); Console.WriteLine($"a.Value : {a.Value}"); //그리고 값에 접근 } else { //Null 이다. Console.WriteLine("a is Null"); } } | cs |
▷2번 결과
a 가 null 일때와 22일때 각각의 출력 결과를 보여 줍니다.
▶Nullable Type 예제 3번(배열에 적용하는 방법)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | static void Main(string[] args) { int?[] arr = new int?[10]; arr[0] = 10; arr[2] = 12; arr[5] = 15; arr[7] = 17; foreach (var num in arr) //var 대신 int? 사용가능. { if (num.HasValue) { //배열에서 값이 할당된 것들만 출력. Console.WriteLine($"num = {num.Value}"); } } } | cs |
▷3번 결과
4. Nullable 총 정리
- nullable 형식은 값형식의 데이터 타입에 Null 값을 넣을수 있도록 해주는 형식입니다.
- HasValue 속성을 통해서 null이 아닌 값이 할당되었는지 확인할 수 있습니다.
- Value 속성을 통해서 할당된 값을 확인할수 있지만, 만약 할당 값이 없다면 예외를 던집니다. 그렇기 때문에 HasValue를 통해서 값이 있는지 확인 후에 Value 속성을 확인하는걸 추천 드립니다.
- GetValueOrDefault() 메소드는 값이 있다면 해당 값을 반환하고, 만약 값이 없다면 해당 데이터 타입의 기본(Default)값을 반환합니다.
'<개인공부> > [C#]' 카테고리의 다른 글
[C#] 타입 조사 Type, 리플렉션(reflection) (0) | 2022.09.11 |
---|---|
[C#] 인덱서 객체(인스턴스)를 배열 처럼 사용해보자 (0) | 2022.09.04 |
[C#] Math.Clamp 메서드(함수) 설명 및 예제 (0) | 2022.07.18 |
[C#] string Trim, TrimEnd, TrimStart에 대해서 (공백제거, 문자제거) (2) | 2019.11.07 |
[C#] string format, 문자열 보간($)을 이용한 문자열 출력방법 (1) | 2019.08.19 |
[C#] Abs 절대값 함수에 대하여. (0) | 2019.07.10 |
[C#] 리터럴(Literal)이란? (7) | 2019.07.05 |
[C#] random, 랜덤 클래스에 대해서 (랜덤함수, 난수생성) (0) | 2019.05.08 |