修复方法覆盖中的 "CS8603: Possible null reference return"

Fixing "CS8603: Possible null reference return" in method override

用下面的代码

abstract class Base
{
    protected abstract T? GetValue<T>([CallerMemberName] string propertyName = "");
}

class Derived : Base
{
    protected override T GetValue<T>([CallerMemberName] string propertyName = "")
    {
        return default;
    }
}

编译器在 return default; 处告诉我,我有一个 CS8603“可能为空引用 return”,这是正确的。但是,如果我将 ? 附加到该方法的 return 类型,以便读取(如抽象方法) protected override T? GetValue<T>([CallerMemberName] string propertyName = "") 编译器告诉我

我如何告诉编译器我的意图 GetValue<T> 可能 return 一个空引用,而不是该方法的 return 类型应该是 Nullable<T>

您可以使用 default 通用约束使其编译:

abstract class Base
{
    protected abstract T? GetValue<T>([CallerMemberName] string propertyName = "");
}

class Derived : Base
{
    protected override T? GetValue<T>([CallerMemberName] string propertyName = "") where T : default
    {
        return default;
    }
}

但是对于值类型 default(T) 将不会返回 default(Nullable<T>) 因此需要使用类型参数的可空值类型来调用它以实现所需的行为。

您可以尝试使用具有不同类型约束和虚拟 T? == null 参数的 2 种方法来解决问题:

abstract class Base
{
    public abstract T? GetValue<T>([CallerMemberName] string propertyName = "", T? _ = null) where T : struct;
    public abstract T? GetValue<T>([CallerMemberName] string propertyName = "", T? _ = null) where T : class;
}

class Derived : Base
{
    public override T? GetValue<T>([CallerMemberName] string propertyName = "", T? _ = null) where T : struct
    {
        return default;
    }
    public override T? GetValue<T>([CallerMemberName] string propertyName = "", T? _ = null) where T : class
    {
        return default;
    }
}

但这取决于您usable/ugly如何决定)

解决方案是将 [return: MaybeNull] 属性放在方法覆盖上,如下所示:

[return: MaybeNull]
protected override T GetValue<T>([CallerMemberName] string propertyName = "")
{
  return default;
}

编译器现在不再列出警告 CS8603。