다음을 통해 공유


Nullalbe 값 형식(C# 참조)

Null 허용 값 형식T?는 기본 값 형식T의 모든 값과 추가 null 값을 나타냅니다. 예를 들어 bool? 변수에는 다음 세 가지 값 중 하나를 할당할 수 있습니다. true, false, null. 기본 값 형식 T 은 nullable 값 형식 자체가 될 수 없습니다.

C# 언어 참조는 가장 최근에 릴리스된 C# 언어 버전을 문서화합니다. 또한 예정된 언어 릴리스의 공개 미리 보기 기능에 대한 초기 설명서도 포함되어 있습니다.

설명서는 언어의 마지막 세 버전 또는 현재 공개 미리 보기에서 처음 도입된 기능을 식별합니다.

팁 (조언)

C#에서 기능이 처음 도입된 시기를 찾으려면 C# 언어 버전 기록에 대한 문서를 참조하세요.

Null 허용 값 형식은 제네릭 System.Nullable<T> 구조체의 인스턴스입니다. 서로 교환 가능한 형식인 T 또는 Nullable<T> 중 하나에서 기본 값 형식 T?의 null 허용 값 형식을 참조할 수 있습니다.

일반적으로 기본 값 형식의 정의되지 않은 값을 나타내야 하는 경우 nullable 값 형식을 사용합니다. 예를 들어 부울(bool) 변수는 true 또는 false만 가능합니다. 그러나 일부 애플리케이션에서는 변수 값이 정의되지 않았거나 누락될 수 있습니다. 예를 들어 데이터베이스 필드에는 값이 전혀 포함되어 true 있지 false않거나, 즉 NULL. 이러한 시나리오에서 bool? 형식을 사용할 수 있습니다.

선언 및 할당

값 형식은 해당 nullable 값 형식으로 암시적으로 변환할 수 있으므로 기본 값 형식에 대해와 같이 nullable 값 형식의 변수에 값을 할당할 수 있습니다. null 값을 할당할 수도 있습니다. 예시:

double? pi = 3.14;
char? letter = 'a';

int m2 = 10;
int? m = m2;

bool? flag = null;

// An array of a nullable value type:
int?[] arr = new int?[10];

nullable 값 형식의 기본값은 .를 null나타냅니다. 속성이 반환false되는 Nullable<T>.HasValue 인스턴스입니다.

Null 허용 값 형식의 인스턴스 검사

nullable 값 형식의 인스턴스를 확인하고 기본 형식 null 의 값을 얻으려면 형식 패턴이 있는 연산자를is 사용합니다.

int? a = 42;
if (a is int valueOfA)
{
    Console.WriteLine($"a is {valueOfA}");
}
else
{
    Console.WriteLine("a does not have a value");
}
// Output:
// a is 42

항상 다음 읽기 전용 속성을 사용하여 nullable 값 형식 변수의 값을 확인하고 가져올 수 있습니다.

다음 예제에서는 속성을 사용하여 HasValue 변수에 값을 표시하기 전에 값이 포함되어 있는지 확인합니다.

int? b = 10;
if (b.HasValue)
{
    Console.WriteLine($"b is {b.Value}");
}
else
{
    Console.WriteLine("b does not have a value");
}
// Output:
// b is 10

다음 예제와 같이 null 속성을 사용하는 대신 null 허용 값 형식 변수를 HasValue과 비교할 수도 있습니다.

int? c = 7;
if (c != null)
{
    Console.WriteLine($"c is {c.Value}");
}
else
{
    Console.WriteLine("c does not have a value");
}
// Output:
// c is 7

nullable 값 형식에서 기본 형식으로 변환

nullable 값 형식의 값을 nullable이 아닌 값 형식 변수에 할당하려면 대신 할당 null할 값을 지정해야 할 수 있습니다. 이렇게 하려면 null 병합 연산 ?? 자를 사용합니다. 동일한 용도로 메서드를 Nullable<T>.GetValueOrDefault(T) 사용할 수도 있습니다.

int? a = 28;
int b = a ?? -1;
Console.WriteLine($"b is {b}");  // output: b is 28

int? c = null;
int d = c ?? -1;
Console.WriteLine($"d is {d}");  // output: d is -1

대신 기본 값 형식의 null을 사용하려면 Nullable<T>.GetValueOrDefault() 메서드를 사용합니다.

다음 예제와 같이 null 허용 값 형식을 null을 허용하지 않는 형식으로 명시적으로 캐스트할 수도 있습니다.

int? n = null;

//int m1 = n;    // Doesn't compile
int n2 = (int)n; // Compiles, but throws an exception if n is null

런타임 시 nullable 값 형식의 값이 null인 경우 명시적 캐스트는 InvalidOperationException을 throw합니다.

null을 허용하지 않는 값 형식 T는 해당 null 허용 값 형식 T?로 암시적으로 변환될 수 있습니다.

리프트 연산자

nullable 값 형식 T? 은 미리 정의된 단항 및 이진 연산 자 또는 값 형식 T 이 지원하는 오버로드된 연산자를 지원합니다. 해제된 연산자라고도 하는 이러한 연산자는 하나 또는 두 피연산자가 모두 있는 경우 반환 null 됩니다null. 그렇지 않으면 연산자는 피연산자의 포함된 값을 사용하여 결과를 계산합니다. 예시:

int? a = 10;
int? b = null;
int? c = 10;

a++;        // a is 11
a = a * c;  // a is 110
a = a + b;  // a is null

참고 항목

bool? 형식의 경우 미리 정의된 &| 연산자는 이 섹션에서 설명된 규칙을 따르지 않습니다. 연산자 평가의 결과는 피연산자 중 하나가 null인 경우에도 Null이 아닐 수 있습니다. 자세한 내용은 부울 논리 연산자 문서의 Nullable 부울 논리 연산자 섹션을 참조하세요.

비교 연산<자, ><=>=피연산자 중 하나 또는 둘 다의 경우 결과는 다음과 같습니다nullfalse. 그렇지 않으면 피연산자의 포함된 값이 비교됩니다. 특정 비교(예 <=: )가 반환 false되므로 반대 비교()가> 반환된다고 true가정하지 마세요. 다음 예제에서는 10이

  • null보다 크지도, 같지도 않고
  • null보다 작지도 않음을 보여줍니다.
int? a = 10;
Console.WriteLine($"{a} >= null is {a >= null}");
Console.WriteLine($"{a} < null is {a < null}");
Console.WriteLine($"{a} == null is {a == null}");
// Output:
// 10 >= null is False
// 10 < null is False
// 10 == null is False

int? b = null;
int? c = null;
Console.WriteLine($"null >= null is {b >= c}");
Console.WriteLine($"null == null is {b == c}");
// Output:
// null >= null is False
// null == null is True

같음 연산==자의 경우 두 피연산자가 null모두면 결과는 .입니다 true. 피연산자 null중 하나만 있으면 결과는 .입니다 false. 그렇지 않으면 피연산자의 포함된 값이 비교됩니다.

같지 않음 연산!=자의 경우 두 피연산자가 null모두면 결과는 다음과 같습니다false. 피연산자 null중 하나만 있으면 결과는 .입니다 true. 그렇지 않으면 피연산자의 포함된 값이 비교됩니다.

두 값 형식 간에 사용자 정의 변환 이 있는 경우 해당 nullable 값 형식 간에도 동일한 변환을 사용할 수 있습니다.

boxing 및 unboxing

다음 규칙은 nullable 값 형식T?의 인스턴스를 입력할 때 적용됩니다.

  • 반환false하는 경우 HasValue boxing 작업은 null 참조를 반환합니다.
  • 반환되는 경우 HasValue boxing 연산은 인스턴스가 아닌 Nullable<T>기본 값 형식T의 해당 값을 확인true합니다.

다음 예제와 같이 값 형식 T의 boxed 값을 해당 null 허용 값 형식 T?로 unbox할 수 있습니다.

int a = 41;
object aBoxed = a;
int? aNullable = (int?)aBoxed;
Console.WriteLine($"Value of aNullable: {aNullable}");

object aNullableBoxed = aNullable;
if (aNullableBoxed is int valueOfA)
{
    Console.WriteLine($"aNullableBoxed is boxed int: {valueOfA}");
}
// Output:
// Value of aNullable: 41
// aNullableBoxed is boxed int: 41

Null 허용 값 형식 식별 방법

다음 예제는 System.Type 인스턴스가 구성된 null 허용 값 형식(지정된 형식 매개 변수 System.Nullable<T>가 포함된 T 형식)을 나타내는지 확인하는 방법을 보여 줍니다.

Console.WriteLine($"int? is {(IsNullable(typeof(int?)) ? "nullable" : "non nullable")} value type");
Console.WriteLine($"int is {(IsNullable(typeof(int)) ? "nullable" : "non-nullable")} value type");

bool IsNullable(Type type) => Nullable.GetUnderlyingType(type) != null;

// Output:
// int? is nullable value type
// int is non-nullable value type

예제에서와 같이 typeof 연산자를 사용하여 System.Type 인스턴스를 만듭니다.

인스턴스가 nullable 값 형식인지 여부를 확인하려면 이전 코드를 사용하여 테스트할 인스턴스를 가져오는 Type 데 메서드를 사용하지 Object.GetType 마세요. nullable 값 형식의 인스턴스에서 Object.GetType 메서드를 호출하는 경우 인스턴스는 Object됩니다. nullable 값 형식의 null이 아닌 인스턴스를 boxing하는 것은 기본 형식의 값을 boxing하는 것과 동일하기 때문에 nullable 값 형식 GetType 의 기본 형식을 나타내는 인스턴스를 반환 Type 합니다.

int? a = 17;
Type typeOfA = a.GetType();
Console.WriteLine(typeOfA.FullName);
// Output:
// System.Int32

그리고 인스턴스가 null 허용 값 형식인지 여부를 확인하는 데 is 연산자를 사용하지 마세요. 다음 예제와 같이 연산자를 사용하여 is nullable 값 형식 인스턴스와 해당 기본 형식 인스턴스의 형식을 구분할 수 없습니다.

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?

대신 첫 번째 예제의 Nullable.GetUnderlyingType 메서드와 typeof 연산자를 사용하여 인스턴스가 nullable 값 형식인지 확인합니다.

참고 항목

이 섹션에 설명된 메서드는 nullable 참조 형식에 적용되지 않습니다.

C# 언어 사양

자세한 내용은 C# 언어 사양의 다음 섹션을 참조하세요.

참고 항목