2

为什么在构造函数中未设置 FieldTwo 时,我没有收到不可为空的警告(或其他警告)?我正在使用 .Net 5.0,并且Nullable项目文件中的选项设置为 true。

  public class MyClass
  {
    public string FieldOne;
    public long FieldTwo;

    public MyClass (string p1, long p2)
    {
      FieldOne = p1;
      // FieldTwo is not set. Where is the non-nullable warning!?
    }
  }

4

2 回答 2

3

long是值类型,不能为空。所以没有理由警告null。我怀疑你想要的是一个字段未初始化的警告。

如果从未分配私有字段,则会导致 CS0649 警告。但是,如果字段 public 或在类中的任何位置被修改,则不会引发此警告。例如,下面是完全可以接受的代码,并且不应该给出警告:

public class MyClass{
    private long myLong;
    public void Increment() => myLong++;
}

如果该字段仅应从构造函数中设置,则应将其声明为只读。但是,公共只读字段不会触发警告,即使它们可能应该触发。请参阅为什么我没有收到有关未初始化的只读字段的警告?.

于 2021-09-15T09:53:16.860 回答
1

long是一个值类型,不能为空。当使用默认值声明时,值类型总是被初始化,在这种情况下0。如果您想存储long?null

无论如何,这些字段都不是属性。这不仅仅是语义。字段是实现细节,甚至是公共字段。它们不被视为类 API 表面的一部分。属性API 的一部分,默认情况下它们会被所有序列化程序序列化(字段不会)并保证事实上拥有公共字段是一种代码味道。

为确保初始化所有属性,您可以使用recordtype 而不是 a class

public record(string PropertyOne, long PropertyTwo);

这会生成一个具有 和 的仅初始化属性的类,PropertyOne以及PropertyTwo一个需要所有属性值的构造函数。连同相等运算符、解构器和ToString()以 JSON 字符串形式返回所有属性的实现。

于 2021-09-15T09:57:23.353 回答