C#9.0记录-不可为空的引用类型和构造函数

C#9.0记录-不可为空的引用类型和构造函数,c#,c#-9.0,C#,C# 9.0,我试了一张简单的唱片: #nullable enable public record Product { public readonly string Name; public readonly int CategoryId; public readonly string Phone; public readonly Address Address; public readonly Manager Manager; } 我收到警告: 不可为空的属性“N

我试了一张简单的唱片:

#nullable enable

public record Product
{
    public readonly string Name;
    public readonly int CategoryId;
    public readonly string Phone;
    public readonly Address Address;
    public readonly Manager Manager;
}
我收到警告:

不可为空的属性“Name”未初始化。考虑将属性声明为可空的。< /P> (除CategoryId外,所有字段均相同) 基本上,如果我理解正确,接受和设置所有字段的构造函数不是由编译器自动生成的(当使用
#nullable enable
时),我必须自己编写,即:

public Product(string Name, int CategoryId, string Phone, Address Address, Manager Manager) {
  this.Name=Name;
  this.CategoryId=CategoryId;
   ...
}
我的问题是,这是正确的吗?我对此感到非常惊讶,因为我认为整个要点是让创建这样的记录变得非常简单,而编写/维护构造函数非常繁琐,尤其是在经常更改的大记录上。
或者我在这里遗漏了什么?

您似乎希望自动生成,但当您使用时,它是自动生成的(通常您会获得所有记录好处),它会自动映射到主构造函数并从主构造函数自动初始化,从而消除NRT警告

这意味着您基本上通过使用普通构造函数语法和添加的
record
关键字来获得所有记录类型sugar:

public record Product(string Name, int CategoryId, string Phone, Address Address, Manager Manager) { }

为什么不正确地将这些属性声明为
init
属性而不是公共只读字段?既然将这些属性设置为
readonly
,就必须对它们进行初始化。编译器无法神奇地知道您希望如何完成此操作。@CamiloTerevinto使用init属性不会更改警告,@juergend removing readonly不会更改警告我认为您不需要手动生成ctor(但我可能错了),但即使在这种情况下,您仍然可以使用
new Product()
因此,您仍然可以使用统一化的成员。对于9.0,至少,如果您想要
#nullable enable
我明白了,如果我尝试这个-see-属性有
{get;set;}
而不是
{get;init;}
那么,我是用“spec”写的。我们实际得到的是当前的“预览”实现。这就是为什么我通常反对测试/讨论预览内容,因为它们可能与我们在发布时得到的结果相去甚远。记录类型的整体思想是使它们成为匿名类型的类型化变体。显然在这些方面还有更多的工作要做:)但我在最新的预览版VS2019中尝试过,即使对象浏览器显示它们为
get;设置init
元数据-