Null 허용 참조 형식으로 코드베이스를 업데이트하여 null 진단 경고 개선

Null 허용 참조 형식을 사용하면 참조 형식의 변수에 null 값을 할당하거나 할당하지 않아야 하는 경우를 선언할 수 있습니다. 코드가 null을 역참조하는 경우 컴파일러의 정적 분석과 경고는 이 기능의 가장 중요한 장점입니다. 사용하도록 설정되면 컴파일러는 코드가 실행될 때 System.NullReferenceException을 throw하지 않는 데 도움이 되는 경고를 생성합니다.

코드베이스가 비교적 작은 경우 프로젝트에서 기능을 켜고, 경고를 처리하고, 향상된 진단을 활용할 수 있습니다. 더 큰 코드베이스에는 시간이 지남에 따라 경고를 처리하기 위해 보다 구조적인 접근 방식이 필요할 수 있으므로 다양한 형식 또는 파일에서 경고를 처리할 때 잠시 동안 기능을 사용할 수 있습니다. 이 문서에서는 이러한 전략과 관련된 코드베이스 및 장단점을 업데이트하는 다양한 전략을 설명합니다. 마이그레이션을 시작하기 전에 null 허용 참조 형식의 개념적 개요를 읽어보세요. 컴파일러의 정적 분석 null-state 값인 maybe-nullnot-null과 null 허용 주석을 설명합니다. 해당 개념과 용어를 잘 알고 있으면 코드를 마이그레이션할 준비가 된 것입니다.

마이그레이션 계획

코드베이스를 업데이트하는 방법에 관계없이 프로젝트에서 null 허용 경고와 null 허용 주석을 사용하도록 설정하는 것이 목표입니다. 해당 목표에 도달하면 프로젝트에서 <nullable>Enable</nullable> 설정을 사용할 수 있습니다. 다른 곳에서 설정을 조정하기 위해 전처리기 지시문이 필요하지 않습니다.

프로젝트의 기본값을 설정하는 것이 가장 좋습니다. 선택 사항은 다음과 같습니다.

  1. 기본값으로 null 허용 사용 안 함: disable은 프로젝트 파일에 Nullable 요소를 추가하지 않는 경우 기본값입니다. 코드베이스에 새 파일을 능동적으로 추가하지 않는 경우 이 기본값을 사용합니다. 기본 작업은 null 허용 참조 형식을 사용하도록 라이브러리를 업데이트하는 것입니다. 이 기본값을 사용한다는 것은 코드를 업데이트할 때 각 파일에 null 허용 전처리기 지시문을 추가한다는 의미입니다.
  2. 기본값 Nullable enable: 새 기능을 능동적으로 개발하는 경우 이 기본값을 설정합니다. 모든 새 코드가 null 허용 참조 형식 및 null 허용 정적 분석을 활용하려고 합니다. 이 기본값을 사용하면 각 파일의 맨 위에 #nullable disable이 추가해야 합니다. 각 파일의 경고를 처리하면서 이러한 전처리기 지시문을 제거합니다.
  3. 기본값으로 null 허용 경고: 2단계 마이그레이션의 경우 이 기본값을 선택합니다. 첫 번째 단계에서 경고를 처리합니다. 두 번째 단계에서 변수의 예상 null-state를 선언하기 위한 주석을 켭니다. 이 기본값을 사용하면 각 파일의 맨 위에 #nullable disable이 추가해야 합니다.
  4. 기본값 Nullable annotations: 경고를 처리하기 전에 코드에 주석을 답니다.

null 허용을 기본값으로 사용하도록 설정하면 모든 파일에 전처리기 지시문을 추가하기 위한 선행 작업이 더 많이 발생합니다. 장점이라면 프로젝트에 추가되는 모든 새 코드 파일에서 nullable을 사용할 수 있습니다. 모든 새 작업은 nullable 인식이므로 기존 코드만 업데이트만 업데이트하면 됩니다. 기본값으로 null 허용을 사용하지 않도록 설정하는 기능은 라이브러리가 안정적이며 개발에서 주로 nullable 참조 형식을 채택하는 데 중점을 두는 경우에 더 효과적입니다. API에 주석을 달 때 nullable 참조 형식을 설정합니다. 마쳤으면 전체 프로젝트에 대해 nullable 참조 형식을 사용하도록 설정합니다. 새 파일을 만들 때 전처리기 지시문을 추가하고 null 허용을 인식하도록 해야 합니다. 팀의 개발자가 위 작업을 잊는 경우 새 코드가 이제 작업의 백로그에 있게 되어 모든 코드에서 nullable을 인식하게 됩니다.

어떤 전략을 선택할지는 프로젝트에서 수행 중인 활성 개발이 얼마나 많은지에 따라 달라집니다. 프로젝트의 완성도와 안정도가 높아질수록 두 번째 전략이 더 효과적입니다. 개발 중인 기능이 많을수록 첫 번째 전략이 더 효과적입니다.

Important

전역 null 허용 컨텍스트는 생성된 코드 파일에 적용되지 않습니다. 두 전략에서 null 허용 컨텍스트는 생성됨으로 표시된 모든 소스 파일에 대해 disabled입니다. 즉, 생성된 파일의 API가 주석 처리되지 않습니다. 다음 네 가지 방법으로 파일은 생성됨으로 표시됩니다.

  1. .editorconfig에서 해당 파일에 적용되는 섹션에 generated_code = true를 지정합니다.
  2. 파일의 맨 위에 있는 주석에 <auto-generated> 또는 <auto-generated/>를 배치합니다. 해당 주석의 모든 줄에 넣을 수 있지만 주석 블록은 파일의 첫 번째 요소여야 합니다.
  3. 파일 이름을 TemporaryGeneratedFile_로 시작합니다.
  4. 파일 이름을 .designer.cs, .generated.cs, .g.cs 또는 .g.i.cs로 종료합니다.

생성기는 #nullable 전처리기 지시문을 사용하여 옵트인할 수 있습니다.

컨텍스트 및 경고 이해

경고와 주석을 사용하도록 설정하면 컴파일러가 형식과 null 허용 여부를 참조하는 방법을 제어할 수 있습니다. 모든 형식에는 다음 세 가지 null 허용 여부 중 하나가 포함됩니다.

  • oblivious: 모든 참조 형식은 주석 컨텍스트가 사용되지 않을 경우 nullable oblivious입니다.
  • nonnullable: 주석이 달리지 않은 참조 형식인 C는 주석 컨텍스트가 사용될 경우 nonnullable입니다.
  • nullable: 주석이 달린 참조 형식인 C?nullable이지만 주석 컨텍스트가 사용되지 않을 경우 경고가 실행될 수 있습니다. var로 선언된 변수는 주석 컨텍스트가 사용될 경우 nullable입니다.

컴파일러는 해당 null 허용 여부에 따라 경고를 생성합니다.

  • nonnullable 형식은 잠재적 null 값이 할당되는 경우 경고를 발생시킵니다.
  • nullable 형식은 maybe-null일 때 역참조되는 경우 경고를 발생시킵니다.
  • oblivious 형식은 maybe-null이고 경고 컨텍스트가 사용될 때 역참조되는 경우 경고를 발생시킵니다.

각 변수에는 null 허용 여부에 따라 달라지는 기본 null 허용 상태가 있습니다.

  • Null 허용 변수의 기본 null-statemaybe-null입니다.
  • Null을 허용하지 않는 변수의 기본 null-statenot-null입니다.
  • Null을 허용하지 않는 oblivious 변수의 기본 null-statenot-null입니다.

Null 허용 참조 형식을 사용하도록 설정하기 전에 코드베이스의 모든 선언은 nullable oblivious입니다. 이는 모든 참조 형식의 기본 null-statenot-null임을 의미하기 때문에 중요합니다.

경고 처리

프로젝트에서 Entity Framework Core를 사용하는 경우 Null 허용 참조 형식 작업에 관한 지침을 참조해야 합니다.

마이그레이션을 시작할 때 먼저 경고만 사용하도록 설정해야 합니다. 모든 선언은 nullable oblivious로 유지되지만 null-statemaybe-null로 변경된 후 값을 역참조할 때 경고가 표시됩니다. 이러한 경고를 처리할 때 더 많은 위치에서 null과 비교 확인하며 코드베이스의 복원력이 향상됩니다. 다양한 상황을 위한 특정 기술을 알아보려면 null 허용 경고를 해결하는 기술 문서를 참조하세요.

다른 코드를 계속하기 전에 각 파일이나 클래스에서 경고를 처리하고 주석을 사용하도록 설정할 수 있습니다. 그러나 형식 주석을 사용하도록 설정하기 전에 컨텍스트가 warnings인 동안 생성된 경고를 처리하는 것이 더 효율적일 수도 있습니다. 이렇게 하면 첫 번째 경고 세트를 처리할 때까지 모든 형식은 oblivious입니다.

형식 주석 사용

첫 번째 경고 세트를 처리한 후 ‘주석 컨텍스트’를 사용하도록 설정할 수 있습니다. 이렇게 하면 참조 형식이 oblivious에서 nonnullable로 변경됩니다. var로 선언된 모든 변수는 nullable입니다. 이 변경으로 인해 새 경고가 발생할 수 있습니다. 컴파일러 경고를 해결하는 첫 번째 단계는 매개 변수와 반환 형식에 ? 주석을 사용하여 인수나 반환 값이 null일 수 있는 경우를 나타내는 것입니다. 이 작업을 수행할 때 목표는 경고를 해결하는 것만이 아닙니다. 무엇보다 컴파일러에서 잠재적 null 값을 사용하는 사용자의 의도로 이해하게 만들어야 합니다.

특성을 통한 형식 주석 확장

변수의 null 상태에 대한 추가 정보를 표현하기 위해 여러 가지 특성이 추가되었습니다. API에 대한 규칙은 모든 매개 변수와 반환 값에 대해 not-null 또는 maybe-null보다 더 복잡할 수 있습니다. 대부분의 API에는 변수가 null일 수 있거나 없는 경우에 대한 더 복잡한 규칙이 있습니다. 이러한 경우에는 특성을 사용하여 해당 규칙을 표현합니다. API의 의미 체계를 설명하는 특성은 null 허용 분석에 영향을 주는 특성에 관한 문서에서 확인할 수 있습니다.

다음 단계

주석을 사용하도록 설정한 후 모든 경고를 처리한 후에는 프로젝트의 기본 컨텍스트를 사용으로 설정할 수 있습니다. 코드에서 null 허용 주석 또는 경고 컨텍스트에 대해 pragma를 추가한 경우 해당 pragma를 제거할 수 있습니다. 시간이 지남에 따라 새 경고가 표시될 수 있습니다. 경고를 발생시키는 코드를 작성할 수 있습니다. Null 허용 참조 형식의 라이브러리 종속성을 업데이트할 수 있습니다. 업데이트하면 해당 라이브러리의 형식이 nullable oblivious에서 nonnullable 또는 nullable로 변경됩니다.

C#의 null 허용 안전성에 대한 학습 모듈에서 이러한 개념을 살펴볼 수도 있습니다.