【发布时间】:2020-04-22 03:55:42
【问题描述】:
请注意,这个问题是关于最新的 C# 8 nullable-references,我已通过以下 <Nullable>enable</Nullable> 声明在 csproj 文件中启用它。
考虑下面的简单代码
class SortedList<T> where T : struct, IComparable, IComparable<T>, IConvertible, IEquatable<T>, IFormattable
{
private Node? _node;
private readonly IComparer<T> _comparer = Comparer<T>.Default;
class Node
{
public Node(T value)
{
Value = value;
}
public T Value { get; }
public Node? Next { get; set; }
public override string ToString()
{
return Value.ToString();
}
}
//rest of code, that isn't important
}
return Value.ToString(); 行给了我一个 CS8603 可能的空引用返回 警告,我的问题实际上为什么会在这里?
我使用where T : struct, IComparable, IComparable<T>, IConvertible, IEquatable<T>, IFormattable 泛型约束来匹配数字类型,Value 实际上是值类型,而不是引用类型。 ToString() 也不会重载到任何值类型,Int32 的默认 implementation(例如)返回不可为空的 string。 MSDN notes to inheritors 也是这么说的
您的
ToString()覆盖不应返回Empty或null字符串。
编译器是否抱怨某种类型,它可以满足泛型约束并从ToString() 返回null?
我可以通过使返回类型为空来避免警告
public override string? ToString()
{
return Value.ToString();
}
或使用空合并运算符
public override string ToString()
{
return Value.ToString() ?? "";
}
或通过 null-forgiving 运算符
public override string ToString()
{
return Value.ToString()!;
}
但是这些选项大多看起来像一个技巧,我正在寻找这种行为的解释,为什么会出现,设计或任何其他原因发生?除了上面的那些,还有什么方法可以避免这个警告?
顺便说一句,这个选项不起作用,警告仍然存在
[return: MaybeNull]
public override string ToString()
{
return Value.ToString();
}
我正在使用 .NET Core 3.1 和 VS 2019 16.4.2,但我认为这在这里并不重要。 提前感谢您的帮助!
【问题讨论】:
-
ToString不应该返回空字符串,返回有意义的东西。 -
Roslyn 中似乎缺少位。向下滚动到 UPDATE 2019-10-08 (II):cezarypiatek.github.io/post/…
-
@Çöđěxěŕ 是的,我已经按照 msdn 的指南进行了操作。
-
@ZorgoZ 感谢更新,没看到这个更新和PR,其实和上面的msdn链接矛盾
-
我记得看到过关于
object.ToString()是否应该返回string?或string的讨论(虽然我现在找不到)。结论是,尽管指导原则是永远不要返回 null,但实际上存在很多可以返回 null 的代码(包括返回对其成员之一调用ToString()的结果的代码)。因此,让object.ToString()返回string会在大多数人的代码中引入很多警告。为了减少噪音,他们决定记录实际发生的情况,但如果您愿意,可以返回string。
标签: c# .net-core c#-8.0 nullable-reference-types