【发布时间】:2021-02-06 05:08:44
【问题描述】:
我正在尝试处理 C# 8 的新可空编译器检查。以下结构给了我一些奇怪的警告。
// This struct gives no warnings
public struct Thing<T> where T : notnull
{
private readonly bool _hasValue;
private readonly T _value;
Thing(T value)
{
_value = value;
_hasValue = value is { };
}
}
// This struct gives warning on the constructor:
// "Non-nullable field "_value" must contain a non-null value before exiting constructor.
// Consider declaring the field as nullable.
public struct Thing<T> where T : notnull
{
private readonly bool _hasValue;
private readonly T _value;
Thing(T value)
~~~~~
{
_value = value;
_hasValue = _value is { };
}
}
// This struct gives two warnings, one on the constructor and one on `_value = value`
// [1] "Non-nullable field "_value" must contain a non-null value before exiting constructor.
// Consider declaring the field as nullable.
// [2] Possible null reference assignment.
// This is true even if I check value for null and throw an ArgumentNullException before the assignment.
public struct Thing<T> where T : notnull
{
private readonly bool _hasValue;
private readonly T _value;
Thing(T value)
~~~~~ // [1]
{
_hasValue = value is { };
_value = value;
~~~~~ // [2]
}
}
我是否创造了一些不可能的情况,编译器无法弄清楚意图?这是与构造函数中的可空引用类型相关的编译器错误吗?我在这里错过了什么?
【问题讨论】:
-
我怀疑notnull 只适用于泛型类型的消费者,而不适用于里面的代码......
-
您的意思是“是对象”检查吗?
-
第一个不工作的例子对我来说很有意义,因为给定初始化规则,该字段的非空保证只能在 构造函数之后回来。实际的错误消息是不幸的,但可能发生错误似乎是合理的。第二个非工作示例对我来说意义不大;我没有充分的理由证明这一点(否则我会发布关于两者的答案)。如果两者都是编译器错误,并且可能已经报告,我不会感到惊讶。你检查了 github repo 吗?