.NET 6 使记录中的属性必需且非空的最佳方法是啥
Posted
技术标签:
【中文标题】.NET 6 使记录中的属性必需且非空的最佳方法是啥【英文标题】:.NET 6 What is the best way to make properties required and non-null in records.NET 6 使记录中的属性必需且非空的最佳方法是什么 【发布时间】:2021-12-21 14:54:16 【问题描述】:我搜索了它的答案,但找不到明确的答案。是的,我知道类似的问题无处不在。我希望我能在这里得到答案。
假设我有一个具有 2 个属性(FirstName、MiddleName)的 Person
类。 FirstName 是必需的,MiddleName 是可选的。
我希望FirstName
属性始终具有不可为空的数据。
以下是我想到的一些选项(但似乎没有一个是完美的)。
一种可选方法是使用记录的简短语法:
// FirstName might be null (bad)
// MiddleName is optional (good)
public record Person(string FirstName, string? MiddleName);
另一种方法是使用null-forgiving operator,但仍然是同样的问题。
// FirstName might be null (bad)
// MiddleName is optional (good)
public record Person
public string FirstName get; init; = null!;
public string? MiddleName get; init;
旧选项是检查构造函数中的输入:
// FirstName is required and will always have some data (good)
// MiddleName is optional (good)
// Long syntax (bad)
public record Person
public string FirstName get; init;
public string? MiddleName get; init;
public Person(string firstName, string? middleName)
// Probably it would be better to check if it is NullOrWhiteSpace.
ArgumentNullException.ThrowIfNull(firstName);
FirstName = firstName;
MiddleName = middleName;
如果最后一个选项是强制非空值的方式,那么我会问:
-
有了所有新的缩短语法,我们真的应该这样做吗?
什么时候应该使用缩短的记录方式?
(我总是想验证必填字段是否具有值并在构造函数中进行)。
【问题讨论】:
"但仍然是同样的问题" -- 我想你从来没有说过真正的问题是什么?同样:“MiddleName 是可选的(好)”——为什么这样好? 记录不应该是所有情况下的首选解决方案。它们带有非常清晰且有限的功能集。如果你不能忍受所有这些特性,要么接受你必须编写比“基本语法”更多的代码,或者只是不使用记录开始。如果您在这些属性中必须有 值,则您的 only 选项是带有保护子句的构造函数。 目前无法混合验证和主要 ctor,e.g. see here。这意味着你基本上被一个明确的 ctor 所困。 是的,目前除了使用 if 语句或?? throw ...
语法的显式构造函数之外,您别无选择。
Related.
【参考方案1】:
我可能会选择在构造函数上强制执行它的经典方式。 当总是需要名字时,并没有真正看到它的缺点
【讨论】:
以上是关于.NET 6 使记录中的属性必需且非空的最佳方法是啥的主要内容,如果未能解决你的问题,请参考以下文章
添加具有空字符串作为默认值且非空约束的列会导致 oracle 数据库的行为不一致