참고 항목
이 문서에서는 nullable 참조 형식을 설명합니다. nullable 값 형식을 선언할 수도 있습니다.
nullable 인식 컨텍스트에 있는 코드에서 nullable 참조 형식을 사용할 수 있습니다. nullable 참조 형식, null 정적 분석 경고 및 null 허용 연산자는 선택적 언어 기능입니다. 모두 기본적으로 꺼져 있습니다. 빌드 설정을 사용하거나 pragmas를 사용하여 코드에서 프로젝트 수준에서 nullable 컨텍스트 를 제어합니다.
C# 언어 참조는 가장 최근에 릴리스된 C# 언어 버전을 문서화합니다. 또한 예정된 언어 릴리스의 공개 미리 보기 기능에 대한 초기 설명서도 포함되어 있습니다.
설명서는 언어의 마지막 세 버전 또는 현재 공개 미리 보기에서 처음 도입된 기능을 식별합니다.
팁 (조언)
C#에서 기능이 처음 도입된 시기를 찾으려면 C# 언어 버전 기록에 대한 문서를 참조하세요.
중요합니다
모든 프로젝트 템플릿은 프로젝트에서 nullable 컨텍스트을 활성화합니다. 이전 템플릿으로 만든 프로젝트에는 이 요소가 포함되지 않으며, 프로젝트 파일에서 사용하도록 설정하거나 pragma를 사용하지 않는 한 이러한 기능은 해제됩니다.
nullable 인식 컨텍스트에서:
- null이 아닌 값을 사용하여 참조 형식
T의 변수를 초기화해야 하며, 해당 값을null할당할 수 없습니다. - 참조 형식
T?null의 변수를 초기화하거나 할당null할 수 있지만 역참조 전에 확인해야null합니다. - null-forgiving 연산자를 형식
T?의 변수m에m!적용하는 경우와 같이 변수는 null이 아닌 것으로 간주됩니다.
컴파일러는 이전 규칙을 사용하여 nullable이 아닌 참조 형식 T 과 nullable 참조 형식 T? 을 구분합니다.
T 형식의 변수와 T? 형식의 변수는 동일한 .NET 형식입니다. 다음 예제에서는 null을 허용하지 않는 문자열 및 nullable 문자열을 선언하고 null 허용 연산자를 사용하여 null을 허용하지 않는 문자열에 값을 할당합니다.
string notNull = "Hello";
string? nullable = default;
notNull = nullable!; // null forgiveness
변수와 notNullnullable 둘 다 형식을 String 사용합니다. nullable이 아닌 형식과 nullable 형식은 모두 동일한 형식을 사용하므로 여러 위치에서 nullable 참조 형식을 사용할 수 없습니다. 일반적으로 nullable 참조 형식을 기본 클래스 또는 구현된 인터페이스로 사용할 수 없습니다. 개체 만들기 또는 형식 테스트 식에서는 nullable 참조 형식을 사용할 수 없습니다. 멤버 액세스 식의 형식으로 nullable 참조 형식을 사용할 수 없습니다. 다음 예제에서는 다음 구문을 보여 줍니다.
public MyClass : System.Object? // not allowed
{
}
var nullEmpty = System.String?.Empty; // Not allowed
var maybeObject = new object?(); // Not allowed
try
{
if (thing is string? nullableString) // not allowed
Console.WriteLine(nullableString);
} catch (Exception? e) // Not Allowed
{
Console.WriteLine("error");
}
nullable 참조 및 정적 분석
이전 섹션의 예제에서는 nullable 참조 형식의 특성을 보여 줍니다. nullable 참조 형식은 새 클래스 형식이 아니라 기존 참조 형식의 주석입니다. 컴파일러는 해당 주석을 사용하여 코드에서 잠재적 null 참조 오류를 찾을 수 있습니다. null을 허용하지 않는 참조 형식과 nullable 참조 형식 간에는 런타임 차이가 없습니다. 컴파일러는 null을 허용하지 않는 참조 형식에 대한 런타임 검사를 추가하지 않습니다. 컴파일 시간 분석에는 이점이 있습니다. 컴파일러는 코드에서 잠재적 null 오류를 찾고 해결하는 데 도움이 되는 경고를 생성합니다. 의도를 선언하고 코드가 해당 의도를 위반하면 컴파일러가 경고를 표시합니다.
중요합니다
Nullable 참조 주석은 동작 변경을 도입하지 않지만 다른 라이브러리는 리플렉션을 사용하여 nullable 및 nullable이 아닌 참조 형식에 대해 다른 런타임 동작을 생성할 수 있습니다. 특히 Entity Framework Core는 nullable 특성을 읽습니다. nullable 참조를 선택적 값으로 해석하고 null을 허용하지 않는 참조를 필수 값으로 해석합니다.
nullable 사용 컨텍스트에서 컴파일러는 nullable 참조 형식 및 null을 허용하지 않는 참조 형식의 변수에서 정적 분석을 수행합니다. 컴파일러는 각 참조 변수의 null-state를 not-null 또는 maybe-null로 추적합니다. null을 허용하지 않는 참조의 기본 상태는 not-null입니다. null 허용 참조의 기본 상태는 maybe-null입니다.
null을 허용하지 않는 참조 형식은 해당 null-state가 not-null이므로 항상 안전하게 역참조해야 합니다. 해당 규칙을 적용하기 위해 null을 허용하지 않는 참조 형식이 null이 아닌 값으로 초기화되지 않는 경우 컴파일러는 경고를 실행합니다. 선언할 지역 변수를 할당해야 합니다. 모든 필드에는 필드 이니셜라이저 또는 모든 생성자에 not-null 값이 할당되어야 합니다. 상태가 maybe-null인 참조에 null을 허용하지 않는 참조가 할당되는 경우 컴파일러가 경고를 실행합니다. 일반적으로 null을 허용하지 않는 참조는 null이 아니며 해당 변수를 역참조할 때 경고가 발생하지 않습니다.
참고 항목
null을 허용하지 않는 참조 형식에 maybe-null 식을 할당하면 컴파일러가 경고를 생성합니다. 그런 다음, 컴파일러는 not-null 식에 할당될 때까지 해당 변수에 대한 경고를 생성합니다.
nullable 참조 형식을 초기화하거나 할당 null 할 수 있습니다. 따라서 정적 분석에서는 역참조되기 전에 변수가 not-null인지 확인해야 합니다. nullable 참조가 null이 아닌 참조 변수에 할당하면 컴파일러 경고가 생성됩니다. 다음 클래스는 해당 경고의 예를 보여 줍니다.
public class ProductDescription
{
private string shortDescription;
private string? detailedDescription;
public ProductDescription() // Warning! shortDescription not initialized.
{
}
public ProductDescription(string productDescription) =>
this.shortDescription = productDescription;
public void SetDescriptions(string productDescription, string? details=null)
{
shortDescription = productDescription;
detailedDescription = details;
}
public string GetDescription()
{
if (detailedDescription.Length == 0) // Warning! dereference possible null
{
return shortDescription;
}
else
{
return $"{shortDescription}\n{detailedDescription}";
}
}
public string FullDescription()
{
if (detailedDescription == null)
{
return shortDescription;
}
else if (detailedDescription.Length > 0) // OK, detailedDescription can't be null.
{
return $"{shortDescription}\n{detailedDescription}";
}
return shortDescription;
}
}
다음 코드 조각은 이 클래스를 사용하는 경우 컴파일러가 경고를 내보내는 위치를 보여 줍니다.
string shortDescription = default; // Warning! non-nullable set to null;
var product = new ProductDescription(shortDescription); // Warning! static analysis knows shortDescription maybe null.
string description = "widget";
var item = new ProductDescription(description);
item.SetDescriptions(description, "These widgets will do everything.");
앞의 예제에서는 참조 변수의 null-state를 확인하는 컴파일러의 정적 분석을 보여 줍니다. 컴파일러는 null 검사 및 할당에 대한 언어 규칙을 적용하여 분석에 대해 알립니다. 컴파일러는 메서드 또는 속성의 의미 체계를 가정할 수 없습니다. Null 검사를 수행하는 메서드를 호출하는 경우 컴파일러는 해당 메서드가 변수의 null-state에 영향을 준다는 것을 알 수 없습니다. API에 특성을 추가하여 컴파일러에 인수 및 반환 값의 의미 체계를 알릴 수 있습니다. .NET 라이브러리의 많은 일반적인 API에는 이러한 특성이 있습니다. 예를 들어, 컴파일러는 IsNullOrEmpty을 null 검사로서 올바르게 해석합니다. null-state 정적 분석에 적용되는 특성에 관한 자세한 내용은 null 허용 특성 문서를 참조하세요.
nullable 컨텍스트 설정
두 가지 방법으로 nullable 컨텍스트를 제어할 수 있습니다. 프로젝트 수준에서 프로젝트 설정을 추가합니다 <Nullable>enable</Nullable> . 단일 C# 소스 파일에서 pragma를 #nullable enable 추가하여 nullable 컨텍스트를 사용하도록 설정합니다.
nullable 전략 설정 문서를 참조하세요. .NET 6 이전에는 새 프로젝트에서 기본 <Nullable>disable</Nullable>사용합니다. .NET 6부터 새 프로젝트에는 프로젝트 파일에 <Nullable>enable</Nullable> 요소가 포함됩니다.
C# 언어 사양
자세한 내용은 C# 언어 사양의 Nullable 참조 형식 섹션을 참조하세요.
참고 항목
.NET