可为空的引用类型,提示参数永远不会为空的静态分析

Nullable reference types, Hint static analysis that parameter is never null

假设我有这个扩展方法

 public static TRes Map<TSource, TRes>(this TSource source, Func<TSource, TRes> mapper) 
        {
            return source is null ? default : mapper(source);
        }

用法:

myobject.Map(obj=> new OtherType(obj,1,2,3));

我收到一条警告,指出 obj 可以为空。有什么办法,在我的扩展方法的声明中,我可以暗示 obj 不能为空的静态分析,因为如果 obj 为空,则不会调用 mapper

我不想用!无处不在,最好从不

所以:

  1. Map 可以在 null.
  2. 上调用
  3. 即使在 null 上调用 MapFunc 参数也不会用 null 输入调用
  4. Map 可以 return null,即使 Func 不 return null

把这些放在一起,然后:

public static TRes? Map<TSource, TRes>(this TSource? source, Func<TSource, TRes> mapper)
{
    return source is null ? default : mapper(source);
}  

TSource? source意味着即使我们在一个可能是null的变量上调用MapTSource仍然被推断为non-nullable。这意味着 Func<TSource, TRes> 不会接收 null 作为其输入。

TRes? 意味着我们被允许 return null,即使 TRes 被推断为可为空(从 mapper 的签名).

See it on SharpLab.

Pre-C#9,如果将泛型参数限制为引用或值类型,则只能在泛型类型参数上使用 ?:仅添加了不受约束的 ?在 C# 9 中。如果您使用的是 C# 8,则需要添加 where TSource : class where TRes : class