在 C# 10.0 中启用了可为空的仅初始化引用属性
Posted
技术标签:
【中文标题】在 C# 10.0 中启用了可为空的仅初始化引用属性【英文标题】:Init-only reference properties with nullable enabled in C# 10.0 【发布时间】:2021-12-20 22:38:01 【问题描述】:我尝试使用仅初始化属性来强制客户端代码在创建类时对其进行初始化,但没有构造函数。它没有按我的计划工作。
这是课程,为了说明这一点而进行了精简。
public class Target
public int Id get; init;
public string Name get; init;
该项目在 .NET 6.0 上,所以我使用的是 C# 10.0。 Nullable 在项目上设置为“已启用”,因此引用属性Name
必须 为非空。让我感到困惑的是,该编译器抱怨 Name 属性在 constructor 之后可能为 null。
CS8618: Non-nullable property 'Name' must contain a non-null value when exiting constructor
当然,这是真的,但使用仅初始化属性的全部意义在于我不想要构造函数。我想强迫人们使用仅初始化属性将Name
初始化为有效的东西。如果我想写一个构造函数,我可以写一个只读属性。
(我意识到我自己可以将 Name
默认为 string.Empty
或其他一些有效值,但我想强制编码器这样做)
C# 10.0 是否为我提供了一种方法来实现我想要的而无需执行以下任何操作?
将引用属性默认为某个非空值(通过构造函数或内联初始化程序) 将属性声明为可为空 完全禁用 nullable 使用record
类型而不是类(因为我想要成员函数)
这可行吗?
我对该主题的搜索将我带到了this post,但我能从中得到的最好的结果是一个指向 Mads Torgensen 博客的链接,该博客讨论了他们计划在 C# 10 中做什么。是否有更新?
【问题讨论】:
【参考方案1】:init
属性不会强制初始化要初始化的值,只有构造函数会这样做。 init
所做的是,if 属性要被初始化,它必须在构造时在对象初始化器中完成(或者在构造器中,如果你有一个) ): 它不保证一定会。
如果您想在这里获得最大的稳健性,请改为通过构造函数对其进行初始化,这样您就可以添加保护子句并保证不可为空的属性。
这就是你想要的(我也是):
Required Properties该提案增加了一种指定在对象初始化期间需要设置属性或字段的方法,强制实例创建者在创建站点的对象初始化器中为成员提供初始值。
【讨论】:
啊,我明白了。我认为这将是一个很好的补充以上是关于在 C# 10.0 中启用了可为空的仅初始化引用属性的主要内容,如果未能解决你的问题,请参考以下文章