关键字 init
(C# 参考)
init
关键字在属性或索引器中定义访问器方法。 init-only 资源库仅在对象构造期间为属性或索引器元素赋值。 init
强制实施不可变性,因此,一旦初始化对象,将无法更改。 init
访问器使调用代码能够使用对象初始值设定项来设置初始值。 相比之下,只有 get
setter 的自动实现属性必须通过调用构造函数来初始化。 具有 private set
访问器的属性可在构造后修改,但只能在类中修改。
以下代码演示 init
自动实现的属性中的访问器:
class Person_InitExampleAutoProperty
{
public int YearOfBirth { get; init; }
}
可能需要实现其中一个访问器来提供参数验证。 可以使用 C# 13 中作为预览功能引入的 field
关键字执行此操作。 关键字 field
访问该属性的编译器合成后盾字段。 以下示例显示了一个属性, init
其中访问器验证参数的范围 value
”
class Person_InitExampleFieldProperty
{
public int YearOfBirth
{
get;
init
{
field = (value <= DateTime.Now.Year)
? value
: throw new ArgumentOutOfRangeException(nameof(value), "Year of birth can't be in the future");
}
}
}
重要
关键字 field
是 C# 13 中的预览功能。 必须使用 .NET 9 并将元素preview
设置为<LangVersion>
项目文件中,才能使用field
上下文关键字。
应注意在 field
具有名为 field
字段的类中使用关键字功能。 新 field
关键字将隐藏属性访问器范围中命名 field
的字段。 可以更改变量的名称 field
,或使用 @
令牌将标识符引用 field
为 @field
。 可以通过阅读关键字的功能规范field
来了解详细信息。
init
访问器可用作表达式主体成员。 示例:
class Person_InitExampleExpressionBodied
{
private int _yearOfBirth;
public int YearOfBirth
{
get => _yearOfBirth;
init => _yearOfBirth = value;
}
}
以下示例为名为 YearOfBirth
的属性同时定义 get
和 init
访问器。 它使用名为 _yearOfBirth
的私有字段备份属性值。
class Person_InitExample
{
private int _yearOfBirth;
public int YearOfBirth
{
get { return _yearOfBirth; }
init { _yearOfBirth = value; }
}
}
init
访问器不强制调用方设置属性。 而它允许调用方使用对象初始值设定项,同时禁止以后的修改。 可以添加 required
修饰符以强制调用方设置属性。 以下示例显示了一个以可为空的值类型作为支持字段的仅 init
属性。 如果调用方未初始化 YearOfBirth
属性,该属性的默认值 null
为:
class Person_InitExampleNullability
{
private int? _yearOfBirth;
public int? YearOfBirth
{
get => _yearOfBirth;
init => _yearOfBirth = value;
}
}
若要强制调用方设置初始非 null 值,可添加 required
修饰符,如以下示例所示:
class Person_InitExampleNonNull
{
private int _yearOfBirth;
public required int YearOfBirth
{
get => _yearOfBirth;
init => _yearOfBirth = value;
}
}
以下示例显示了 private set
、read only 和 init
属性之间的区别。 private set 版本和 read only 版本都需要调用方使用添加的构造函数来设置 name 属性。 通过 private set
版本,人员可在构造实例后更改其名称。 init
版本不需要构造函数。 调用方可使用对象初始值设定项初始化属性:
class PersonPrivateSet
{
public string FirstName { get; private set; }
public string LastName { get; private set; }
public PersonPrivateSet(string first, string last) => (FirstName, LastName) = (first, last);
public void ChangeName(string first, string last) => (FirstName, LastName) = (first, last);
}
class PersonReadOnly
{
public string FirstName { get; }
public string LastName { get; }
public PersonReadOnly(string first, string last) => (FirstName, LastName) = (first, last);
}
class PersonInit
{
public string FirstName { get; init; }
public string LastName { get; init; }
}
PersonPrivateSet personPrivateSet = new("Bill", "Gates");
PersonReadOnly personReadOnly = new("Bill", "Gates");
PersonInit personInit = new() { FirstName = "Bill", LastName = "Gates" };
C# 语言规范
有关详细信息,请参阅 C# 语言规范。 该语言规范是 C# 语法和用法的权威资料。