Nullable 형식 사용




nullable 형식은 기본 형식의 모든 값과 추가 null 값을 나타낼 수 있습니다. nullable 형식은 다음과 같은 두 가지 방법 중 하나로 선언됩니다.

System.Nullable<T> variable

또는

T? variable

T는 nullable 형식의 기본 형식입니다. T는 struct를 비롯한 모든 값 형식일 수 있으나, 참조 형식일 수는 없습니다.


object? sdf;  //컴파일 오류


nullable 형식을 사용할 수 있는 경우의 예를 들기 위해 일반 부울 변수가 두 가지 값 true와 false를 가질 수 있는 방법을 고려합니다. “정의되지 않음”을 의미하는 값은 없습니다. 많은 프로그래밍 응용 프로그램(특히, 데이터베이스 상호 작용)에서 변수는 정의되지 않은 상태로 발생할 수 있습니다. 예를 들어 데이터베이스의 필드는 true 또는 false 값을 포함할 수 있지만, 전혀 값을 포함하지 않을 수도 있습니다. 마찬가지로, 초기화되지 않았음을 나타내기 위해 참조 형식을 null로 설정할 수 있습니다.

이 차이로 인해 상태 정보, 특수 값 사용 등을 저장하는 데 사용되는 추가 변수와 관련한 추가 프로그래밍 작업이 발생할 수 있습니다. C#에서는 nullable 형식 한정자를 사용하여 정의되지 않은 값을 나타내는 값 형식 변수를 만들 수 있습니다.



nullable 형식의 예

nullable 형식에 대한 기준으로 모든 값 형식을 사용할 수 있습니다. 예:


1
2
3
4
5
int? i = 10;
double? d1 = 3.14;
bool? flag = null;
char? letter = 'a';
int?[] arr = new int?[10];
cs

nullable 형식의 멤버

nullable 형식의 각 인스턴스에는 다음과 같은 두 개의 public 읽기 전용 속성이 포함됩니다.

  • HasValue

    HasValue는 bool 형식입니다. 변수가 null이 아닌 값을 포함한 경우 true로 설정됩니다.

  • Value

    Value는 기본 형식과 같은 형식입니다. HasValue가 true이면 Value에는 의미 있는 값이 포함됩니다. HasValue가 false이면 Value에서는 InvalidOperationException을 throw합니다.

이 예제에서 HasValue 멤버는 변수를 표시하려고 하기 전에 변수가 값을 포함하는지를 테스트하는 데 사용됩니다.

1
2
3
4
5
6
7
8
9
10
int? x = 10;
if (x.HasValue)
{
    System.Console.WriteLine(x.Value);
}
else
{
    System.Console.WriteLine("Undefined");
}
 

cs


값에 대한 테스트는 다음 예제처럼 수행할 수도 있습니다.


1
2
3
4
5
6
7
8
9
int? y = 10;
if (y != null)
{
    System.Console.WriteLine(y.Value);
}
else
{
    System.Console.WriteLine("Undefined");
}



명시적 변환

nullable 형식은 캐스트를 사용하여 명시적으로 또는 Value 속성을 사용하여 일반 형식으로 캐스팅할 수 있습니다. 예:


1
2
3
4
5
int? n = null;
 
//int m1 = n;      // Will not compile.
int m2 = (int)n;   // Compiles, but will create an exception if n is null.
int m3 = n.Value;  // Compiles, but will create an exception if n is null.


두 데이터 형식 간에 사용자 정의 변환이 정의된 경우 이러한 데이터 형식의 nullable 버전에도 같은 변환을 사용할 수 있습니다.

암시적 변환

nullable 형식의 변수는 다음 예제와 같이 null 키워드를 사용하여 null로 설정할 수 있습니다.

int? n1 = null;


일반 형식에서 nullable 형식으로의 변환은 암시적입니다.

int? n2; n2 = 10; // Implicit conversion.


연산자

미리 정의된 단항 및 이항 연산자와 값 형식에 대해 존재하는 모든 사용자 정의 연산자는 nullable 형식에도 사용할 수 있습니다. 이러한 연산자는 피연산자가 null인 경우 null 값을 생성하고, 그렇지 않으면 연산자는 포함된 값을 사용하여 결과를 계산합니다. 예:

1
2
3
4
5
6
int? a = 10;
int? b = null;
 
a++;         // Increment by 1, now a is 11.
= a * 10;  // Multiply by 10, now a is 110.
= a + b;   // Add b, now a is null.
cs

nullable 형식과의 비교를 수행할 때 nullable 형식 중 하나의 값이 null이고 나머지는 null이 아닌 경우 모든 비교는 !=(같지 않음)을 제외하고는 false로 계산됩니다. 특정 비교에서는 false를 반환하고 그 반대의 경우에는 true를 반환한다고 가정하지 않는 것이 중요합니다. 다음 예제에서 10은 null보다 크지 않고, 작지 않고, 같지도 않습니다. num1 != num2만 true로 계산됩니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
int? num1 = 10;
int? num2 = null;
if (num1 >= num2)
{
    Console.WriteLine("num1 is greater than or equal to num2");
}
else
{
    // This clause is selected, but num1 is not less than num2.
    Console.WriteLine("num1 >= num2 returned false (but num1 < num2 also is false)");
}
 
if (num1 < num2)
{
    Console.WriteLine("num1 is less than num2");
}
else
{
    // The else clause is selected again, but num1 is not greater than
    // or equal to num2.
    Console.WriteLine("num1 < num2 returned false (but num1 >= num2 also is false)");
}
 
if (num1 != num2)
{
    // This comparison is true, num1 and num2 are not equal.
    Console.WriteLine("Finally, num1 != num2 returns true!");
}
 
// Change the value of num1, so that both num1 and num2 are null.
num1 = null;
if (num1 == num2)
{
    // The equality comparison returns true when both operands are null.
    Console.WriteLine("num1 == num2 returns true when the value of each is null");
}
 
/* Output:
 * num1 >= num2 returned false (but num1 < num2 also is false)
 * num1 < num2 returned false (but num1 >= num2 also is false)
 * Finally, num1 != num2 returns true!
 * num1 == num2 returns true when the value of each is null
 */



둘 다 null인 두 nullable 형식의 같음 비교는 true로 계산됩니다.

?? 연산자

?? 연산자는 nullable 형식이 nullable 형식이 아닌 형식에 할당된 경우 반환되는 기본값을 정의합니다.

말이 좀 이상한데 쉽게 말한다면 c가 null 인경우 -1 을 ? 아닌 변수 d 에 할당한다(초기화 한다)로 보면 됩니다



int? c = null;

// d = c, unless c is null, in which case d = -1.
int d = c ?? -1;

이 연산자는 여러 nullable 형식에도 사용할 수 있습니다. 예:


아래 같은 경우에는 e 와 f 가 모두 null 임으로 -1 이 g 에 할당됩니다


int? e = null;
int? f = null;

// g = e or f, unless e and f are both null, in which case g = -1.
int g = e ?? f ?? -1;


bool? 형식

bool? nullable 형식은 세 가지 값 truefalse 및 null을 포함할 수 있습니다. 
bool?에서 bool로 캐스팅하는 방법에 대한 자세한 내용은 방법: bool?에서 bool로 안전하게 캐스팅을 참조하세요.

nullable 부울은 SQL에서 사용되는 부울 변수 형식과 유사합니다. & 및 | 연산자에 의해 생성된 결과가 SQL의 삼중값 부울 형식과 일치하도록 다음과 같은 미리 정의된 연산자가 제공됩니다.

bool? operator &(bool? x, bool? y)

bool? operator |(bool? x, bool? y)

다음 표는 이러한 연산자의 결과를 보여 줍니다.

Xyx&yx|y
truetruetruetrue
trueFalsefalsetrue
truenullnulltrue
FalsetrueFalsetrue
FalseFalseFalseFalse
FalsenullFalsenull
nulltruenulltrue
nullFalseFalsenull
nullnullnullnull




ref : https://docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/nullable-types/using-nullable-types





+ Recent posts