.NET 6 使记录中的属性为必需且非空的最佳方法是什么

Mis*_*sky 3 c# .net-6.0 c#-10.0

我寻找答案,但找不到明确的答案。是的,我知道类似的问题到处都存在。我希望我能在这里得到答案。

假设我有一个Person具有 2 个属性(FirstName、MiddleName)的类。名字是必需的,中间名是可选的。

我希望该FirstName属性始终具有不可为空的数据。

以下是我想到的一些选择(但似乎没有一个是完美的)。

一种可选的方法是使用记录的短语法:

// FirstName might be null (bad)
// MiddleName is optional (good)
public record Person(string FirstName, string? MiddleName);
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用null-forgiving 运算符,但仍然存在同样的问题。

// FirstName might be null (bad)
// MiddleName is optional (good)
public record Person
{
    public string FirstName { get; init; } = null!;

    public string? MiddleName { get; init; }
}
Run Code Online (Sandbox Code Playgroud)

旧的选项是检查构造函数中的输入:

// 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果最后一个选项是强制执行非空值的方法,那么我会问:

  1. 有了所有新的缩短语法,我们真的应该这样做吗?
  2. 什么时候应该使用简化的记录方式?(我总是想验证必填字段是否具有值并在构造函数中执行此操作)。

Mis*_*sky 5

C# 11.0预览版中,可以required在属性声明中使用。

public record Person
{
    public required string FirstName { get; init; }

    public string? MiddleName { get; init; }
}
Run Code Online (Sandbox Code Playgroud)

可以在这里找到一篇关于它的很好的解释文章。

  • 这个答案是完全错误的。.NET 6 不正式支持 C# 11,并且必需成员根本无法在 .NET 6 上运行。 (2认同)