[c#] C # 8의 널 입력 불가능 참조 유형이 런타임에서 널이 될 수 있습니까?

nullable이 아닌 변수에 null이 없다는 보장은 실제로 없습니다. nullable이 아닌 하나의 속성이있는 클래스가 있다고 상상해보십시오.

public class Foo
{
    public Foo(string test)
    {
        Test = test;
    }
    public string Test {get;set;}
}

이제는 null이 될 수없는 것처럼 보일 수 있습니다. 그러나이 클래스를 nullable 컨텍스트를 사용하지 않는 다른 라이브러리로 참조하면 아무것도 null을 보내지 않습니다.

이것이 맞습니까? 아니면 이것을 확인하는 런타임 검사가 있습니까?



답변

이것은 MS가 말한 것입니다 ( https://docs.microsoft.com/en-us/dotnet/csharp/tutorials/upgrade-to-nullable-references#interfaces-with-external-code ) :

코드가 nullable 주석 컨텍스트를 활성화하여 컴파일 된 경우에도 컴파일러는 퍼블릭 API에 대한 모든 호출의 유효성을 검사 할 수 없습니다. 또한 아직 널 입력 가능 참조 유형을 사용하지 않는 프로젝트에서 라이브러리를 사용할 수 있습니다. 널 입력 불가능 유형으로 선언 한 경우에도 공용 API에 대한 입력의 유효성을 검증하십시오.


답변

누군가는 항상 할 수 있습니다

var myFoo = new Foo(null);

도메인 기반 디자인을 사용할 수 있습니까?

public class Foo
{
    public Foo(string test)
    {
         if (string.IsNullOrWhiteSpace(test))
             throw new ArgumentNullException(nameof(test));

         Test = test;
    }
    public string Test {get;private set;}
}


답변

맞습니다. 새 기능을 사용하지 않는 다른 코드는이 속성에 null을 할당 할 수 있습니다. 런타임 검사는 더 간단한 힌트 일뿐입니다.

런타임 검사를 원한다면 언제든지 직접 할 수 있습니다.

public string Test { get; set{ if (value == null) throw new ArgumentNullException() } }

대부분 의 코드 에서 null이되지 않도록 보장 할 수 있으므로 최상위 공용 API에 가드를 추가하고 클래스가 적절하게 봉인되어 있는지 확인하면됩니다.

물론 사람들은 여전히 ​​리플렉션을 사용하여 코드를 강화 할 수는 있지만 그 코드에 반영 할 수 있습니다


답변

자신의 코드에서도, 당신이 그렇게하기로 선택한다면 null, 널 용서 연산자를 사용하여를 전달할 수 있습니다 . null!컴파일러의 Nullability 분석에 관한 한 Null이 아닌 것으로 간주됩니다.


답변

null 검사를 처리하고 코드를 읽을 수있게하려면 Null Object Design 패턴을 제안합니다.

더 읽을 거리 :

https://www.c-sharpcorner.com/article/null-object-design-pattern/

기본적으로 동일한 인터페이스에서 파생되고 null 인스턴스가있는 새 객체를 생성합니다.

예:

public class NullExample : IExample
{
    private static NullExample _instance;
    private NullExample()
    { }

    public static NullExample Instance
    {
        get {
            if (_instance == null)
                return new NullExample();
            return _instance;
        }
    }

    //do nothing methods  
    public void MethodImplementedByInterface1()
    { }

    public void MethodImplementedByInterface1()
    { }
}  

널은 피할 수 없지만 깨끗하게 확인할 수 있습니다.


답변