【问题标题】:Fixing "CS8603: Possible null reference return" in method override修复方法覆盖中的“CS8603:可能的空引用返回”
【发布时间】:2022-01-15 01:10:15
【问题描述】:

使用以下代码

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“可能的空引用返回”,这是真的。但是,如果我将 ? 附加到该方法的返回类型,以便读取(如抽象方法)protected override T? GetValue&lt;T&gt;([CallerMemberName] string propertyName = ""),编译器会告诉我

  • CS0508 'Derived.GetValue(string)':返回类型必须为 'T' 以匹配覆盖的成员 'Base.GetValue(string)'。
  • CS0453 类型“T”必须是不可为空的值类型,才能在泛型类型或方法“Nullable”中用作参数“T”。

我如何告诉编译器我的意图 GetValue&lt;T&gt; 可能返回一个空引用,而不是该方法的返回类型应该是 Nullable&lt;T&gt;

【问题讨论】:

  • T 可以仅限于类还是需要同时支持引用和值类型?
  • T 应该被允许是任何东西——引用类型和值类型。
  • 我原以为您可以执行default(T) is null 检查并满足编译器的要求,但事实证明这还不够。根据这篇帖子stackoverflow.com/a/59328672/1165998,这似乎是不可能的。

标签: c# nullable-reference-types


【解决方案1】:

你可以使用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&lt;T&gt;),因此需要使用可空值类型为类型参数调用它以实现所需的行为。

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

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;
    }
}

但由您决定它的可用性/丑陋程度)

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2023-04-06
      • 1970-01-01
      • 2014-11-21
      • 1970-01-01
      • 2021-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多