在一条记录中定义一个 属性 两次
Defining a property in a record twice
在 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 }
这种行为是正确的还是错误?
如果正确,在什么情况下有用?
我希望编译器要么拒绝此代码并返回类似 'The type Cat
already contains a definition for PawCount
' 的错误,要么考虑属性 在构造函数和主体中相同,从构造函数执行其初始化。
后一种变体可能有助于为 属性 提供自定义 getter and/or 初始值设定项,而无需重写其主体中位置记录的所有属性。
实际行为对我来说毫无意义。
正确的做法是:
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;
}
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# 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 }
这种行为是正确的还是错误? 如果正确,在什么情况下有用?
我希望编译器要么拒绝此代码并返回类似 'The type Cat
already contains a definition for PawCount
' 的错误,要么考虑属性 在构造函数和主体中相同,从构造函数执行其初始化。
后一种变体可能有助于为 属性 提供自定义 getter and/or 初始值设定项,而无需重写其主体中位置记录的所有属性。
实际行为对我来说毫无意义。
正确的做法是:
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;
}
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
属性,因此除非您使用它,否则只会默默地忽略该参数你自己明确。