Ключевое init
слово (справочник по C#)
Ключевое init
слово определяет метод доступа в свойстве или индексаторе. Метод задания только для инициализации назначает значение свойству или элементу индексатора только во время построения объекта. Принудительное init
применение неизменяемости, поэтому после инициализации объекта его нельзя изменить. Метод init
доступа позволяет вызывать код для использования инициализатора объектов для задания начального значения. В качестве контраста автоматически реализованное свойство с только методом get
задания необходимо инициализировать путем вызова конструктора. Свойство с методом private set
доступа можно изменить после построения, но только в классе.
Следующий код демонстрирует init
метод доступа в автоматически реализованном свойстве:
class Person_InitExampleAutoProperty
{
public int YearOfBirth { get; init; }
}
Для проверки параметров может потребоваться реализовать один из методов доступа. Это можно сделать с помощью ключевого field
слова, представленного как предварительная версия функции в C# 13. Ключевое 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. Для использования контекстного ключевого field
слова необходимо использовать .NET 9 и задать <LangVersion>
элемент preview
в файле проекта.
Следует тщательно использовать функцию field
ключевого слова в классе с именем field
поля. Новое field
ключевое слово тенирует поле с именем field
в области доступа к свойствам. Можно изменить имя переменной field
или использовать @
маркер для ссылки на field
идентификатор как @field
. Дополнительные сведения см. в спецификации компонента для ключевого field
слова.
Метод init
доступа можно использовать в качестве элемента с выражением. Пример:
class Person_InitExampleExpressionBodied
{
private int _yearOfBirth;
public int YearOfBirth
{
get => _yearOfBirth;
init => _yearOfBirth = value;
}
}
В приведенном ниже примере определен как метод доступа get
, так и метод доступа init
для свойства с именем YearOfBirth
. Для возвращения значения свойства в нем используется закрытое поле с именем _yearOfBirth
.
class Person_InitExample
{
private int _yearOfBirth;
public int YearOfBirth
{
get { return _yearOfBirth; }
init { _yearOfBirth = value; }
}
}
Метод init
доступа не принудительно задает свойство вызывающим абонентам. Вместо этого он позволяет вызывающим пользователям использовать инициализатор объектов при запрете последующего изменения. Модификатор можно добавить required
для принудительного задания свойства вызывающим. В следующем примере показано init
только свойство с типом значения NULL в качестве резервного поля. Если вызывающий объект не инициализирует 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
чтения и init
свойства. Приватный набор версии и единственная версия для чтения требуют, чтобы вызывающие пользователи использовали добавленный конструктор для задания свойства 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#.