【问题标题】:MaybeNull attribute warns on null reference returnMaybeNull 属性警告空引用返回
【发布时间】:2020-04-20 12:07:28
【问题描述】:

作为转向 C# 8 可空引用类型的一部分,我遇到了以下代码(简化):

public string GetIfExists(string key)
{
    dict.TryGetValue(key, out var value);

    return value;
}

return 行警告可能返回空引用,这是有道理的。所以我尝试用[return: MaybeNull] 属性注释该方法,但警告仍然令我惊讶。从documentation,我了解到这个属性将返回类型标记为可选null,即使实际类型不允许。

看来我避免警告的唯一选择是标记返回类型string?。那么[return: MaybeNull]有什么用呢?

【问题讨论】:

  • docs.microsoft.com/en-us/dotnet/csharp/nullable-attributes: "你可以应用一些属性:......来完整描述参数和返回值的空状态......你向编译器提供的关于允许或禁止空值时,您的 API 用户将获得更好的警告。”
  • 我尝试在您的方法上使用[return: MaybeNull],警告消失了。您能否显示您尝试过的确切代码,然后还显示重建后警告仍然存在的屏幕截图?
  • @LasseV.Karlsen 我认为这个问题在我提出这个问题后在编译器中得到了解决。我不能再复制它了。
  • 好的,很高兴你设法解决它:)

标签: c#-8.0 nullable-reference-types


【解决方案1】:

来自文档:

[return: MaybeNull] 通知调用者合约暗示了一个不可为空的类型,但返回值实际上可能为空。当您的 API 应该是不可为空的类型(通常是泛型类型参数)时,请使用 MaybeNull 属性,但可能会在某些情况下返回 null。

这意味着您希望在希望显示警告而不更改合同的情况下使用该属性。

似乎已创建该属性以帮助在两种情况下强制执行不可为空性(传播警告以强制用户检查是否为空):

  • 在无法更改函数签名的情况下。
  • 在涉及泛型的情况下。由于它们的性质,泛型更难处理,您可能会发现自己处于不允许拥有T? 的情况,但您仍然希望该方法的用户知道结果需要检查。

您必须摆脱警告的唯一方法是将返回类型更改为string?(或return value!;,但这是一个谎言:p)。

【讨论】:

  • 对于reference type ? 不是(不能是)签名的一部分。这是annotation 不是声明。因此首先• 是无意义的。对于泛型,从使用角度来看,T? 返回类型和[return: MaybeNull] 之间没有区别。
【解决方案2】:

您的问题无法重现。

public string GetIfExists ( string key )
{
  new Dictionary<string, string>().TryGetValue (key, out string value); // Warning  CS8600  Converting null literal or possible null value to non-nullable type.
  return value; // Warning  CS8603  Possible null reference return.
}
[return: MaybeNull]
public string GetIfExists ( string key )
{
  new Dictionary<string, string>().TryGetValue (key, out string? value);
  return value;
}

(没问题‼)


从泛型的使用角度来看,T? return type[return: MaybeNull] 之间没有区别。(也适用于 reference type。)

[return: MaybeNull]
public T Find<T> ( ) => default;
public T? Find2<T> () => default;    
public T Find3<T> ( ) => default;  // Warning   CS8603  Possible null reference return.

void Test ()
{
  object x = Find<object> (); // Warning    CS8600  Converting null literal or possible null value to non-nullable type.
  object x2 = Find2<object> (); // Warning  CS8600  Converting null literal or possible null value to non-nullable type.
  object x3 = Find3<object> ();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-02
    • 1970-01-01
    • 1970-01-01
    • 2010-11-23
    • 2022-06-14
    • 1970-01-01
    • 1970-01-01
    • 2023-02-14
    相关资源
    最近更新 更多