c# - 两次定义记录中的属性

标签 c# c#-9.0

在C#9中,可以在其主要构造函数及其主体中的记录中定义一个具有相同名称的属性:

record Cat(int PawCount)
{
    public int PawCount { get; init; }
}
这段代码编译没有错误。
初始化此类记录的实例时,将完全忽略提供给构造函数的值:
Console.WriteLine(new Cat(4));
Console.WriteLine(new Cat(4) { PawCount = 1 });
打印
Cat { PawCount = 0 }
Cat { PawCount = 1 }

这种行为是正确的还是错误?
如果正确,在什么情况下有用?
我希望编译器拒绝该代码,并产生类似“类型Cat已经包含PawCount的定义”之类的错误,或者考虑构造函数和主体中的属性相同,并从构造函数中执行其初始化。
后一种变体可能非常有用,可以为属性提供自定义的getter和/或初始化器,而不必在其主体中重写位置记录的所有属性。
实际的行为对我来说毫无意义。

最佳答案

正确的方法是:

record Cat(int PawCount)
{
    public int PawCount { get; init; } = PawCount;
}
这很有用,因为它允许您执行例如验证
record Cat(int PawCount)
{
    private int _pawCount;
    public int PawCount {
        get => _pawCount;
        init => _pawCount = value < 0 ? throw new ArgumentException() : value; 
    } = PawCount;
}
规范在这里:https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/records.md#members-of-a-record-type

Members are synthesized unless a member with a "matching" signature is declared in the record body or an accessible concrete non-virtual member with a "matching" signature is inherited. Two members are considered matching if they have the same signature or would be considered "hiding" in an inheritance scenario.


因此,由于已经存在与该参数同名的属性,因此编译器将不会合成PawCount属性,因此除非您自己明确使用该参数,否则它会默默地忽略该参数。

关于c# - 两次定义记录中的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65110563/

相关文章:

c# - 轻松地将 BitConverter.GetBytes 上存在的所有重载用于我自己的方法

javascript - 如何获取asp :Table cell values using Javascript?

C#源代码生成器-警告CS8032 : An instance of analyzer cannot be created

C# 9 记录有 ToString() 的 { propertyName=value } 输出,如何从中返回记录类型?

c# - netstandard 代码生成器 Microsoft.Data.SqlClient 抛出 FileNotFound System.Security.Principal.Windows,Version=4.1.1.0

C# 可为空性未正确推导

c# - 并发访问数据库——防止两个用户获取相同的值

c# - 将 Web API 用于 Windows 服务以通过轮询接收命令和执行任务?

c# - Asp.net C# Webform 表单生成器/生成器

c# - Visual Studio 未显示 WSL2 启动配置文件