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
}
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, T
와 notnull
제약 조건을 사용하는 것을 허용하지 않습니다 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] 삭제
몇 마디 만하겠습니다