Null 허용이 가능한 C # 환경에서 여전히 NotNull 특성을 사용하는 것이 유용합니까? 아니면 차이가 없습니까?

스벤 크 라우터

Null 허용이 가능한 C # 환경에서 여전히 NotNull 특성을 사용 하는 것이 유용 합니까? 아니면 차이가 없습니까?

매개 변수가 있다고 가정 해 보겠습니다.

사례 a

public static SomeExtensionMethod<T>([NotNull] this IList<T> source) 
{
    // stuff
}

사례 b

public static SomeExtensionMethod<T>([NotNull] this T source) where T: notnull
{
    // stuff
}
Theraot

NotNull발신자 코드에 대한 힌트 역할을합니다. 무엇을 전달할 수 있는지가 아니라 무엇을 전달했는지 여부에 대해서는 호출 후 null이됩니다.

매개 변수를 nullable로 표시하고 NotNull특성을 사용하면 Roslyn은을 전달할 수 null있으며 해당 지점 이후에 참조가 null이 아니라고 가정합니다. null이 전달되면 throw하여이 계약을 만족시킬 수 있습니다. 이것은 어설 션을 만드는 데 유용 할 수 있습니다.

public static void NotNullList<T>([NotNull] this IList<T>? source) 
{
    if (source == null)
    {
         throw new ArgumentNullException(nameof(source));
    }
    // stuff
}

아마도 우리는 그러한 주장이 필요하지 않다고 생각하고있을 것입니다. 그러나 참조가 null이 될 수 있고 null 케이스를 버릴 필요가있을 때. 물론, NotNullIfNotNull대신 활용할 수 있습니다 .

슬프게도 마지막으로 확인했을 때 참조를 null과 비교하면 참조가 null이 될 수 있다는 Roslyn에 대한 힌트로 작동합니다. 따라서 null을 삭제하는 간단한 if 문이 예상대로 작동하지 않을 수 있습니다.


의 또 다른 용도 NotNull는 for ref또는 out매개 변수입니다. 참조가 null이 아님을 호출자에게 보장합니다.

이 예제에서는 전달 null이 허용되며 메서드 실행 후 참조가 null이 아님을 보장합니다. 즉, null을 전달하면 throw하거나 초기화합니다.

public static void DoSomethingWithRef<T>([NotNull] ref IList<T>? source) 
{
    if (source == null)
    {
         source = new List<T>();
    }
    // stuff
}

물론 [return: NotNull]반환 값이 null이 아니라는 호출자에게 통신하는 데 사용할 수 있습니다 .


이제 제네릭은 어떻습니까?

제네릭을 제한하지 않는 경우 제네릭 인수로 nullable 또는 not nullable 참조 유형을 지정할 수 있습니다.

var x = new List<string?>();
var y = new List<string>();

제약 조건이없는 제네릭 코드에서는 notnull제네릭 형식이 nullable 형식인지 아니면 nullable 형식이 아닌지 알 수 없습니다. 따라서 NotNull속성은 무언가가 null이 아님을 보장 할 수있을 때 호출자와 통신하는 데 유용합니다.


class또는 struct제약은와 잘 섞이지 않는다는 점을 명심하십시오 notnull. 이러한 제약 조건이있는 코드는 notnull. 사실 notnull전파하는 경향이 있습니다. Futhermore, Tnotnull제약 조건을 사용하는 것을 허용하지 않습니다 T?.

이러한 이유 때문에 notnull가능한 제약을 합니다. 때로는 자신을 반복하기도합니다.

    public static IEnumerable<T> ExploreSequenceUntilNull<T>(T? initial, Func<T, T?> next)
        where T : class
    {
        // ...
    }

    public static IEnumerable<T> ExploreSequenceUntilNull<T>(T? initial, Func<T, T?> next)
        where T : struct
    {
        // ...
    }

여기에서의 입력 next이 null이 아니라고 말하고 있지만 null을 반환하는 것은 괜찮습니다. 것도 OK입니다 initial매개 변수가 null이 될 수 있습니다. 그러나 반환 된 항목 IEnumerable에는 null이 없습니다. 예, 과부하 해결은 어느 것을 호출해야하는지 알아낼 수 있습니다. 그리고 예, 일반적인 제약을 제외하고 소스에서 동일합니다. 아시다시피 구조체의 T?의미 는 실제 코드가 다릅니다 Nullable<T>.


그 반대 ( MaybeNull)는 어떻습니까? 제한되지 않은 제네릭에서 반환 된 참조가 null 일 수 있음을 알리는 데 유용합니다 (제네릭 형식이 null을 허용하는 경우). 제네릭 유형의 매개 변수와 필드에도 유사하게 유용합니다.

물론 ?제네릭 유형을 다루지 않을 때만 사용할 수 있습니다 .

에 관심이있을 수도 있습니다 MaybeNullWhen.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관