A init
palavra-chave (Referência de C#)
A palavra-chave init
define um método de acessador em uma propriedade ou em um indexador. Um setter somente de inicialização atribui um valor à propriedade ou ao elemento indexador somente durante a construção do objeto. Um init
impõe imutabilidade, pelo que, uma vez inicializado, o objeto não pode ser alterado. Um acessador init
permite que o código de chamada use um inicializador de objeto para definir o valor inicial. Por outro lado, uma propriedade implementada automaticamente com apenas um get
setter deve ser inicializada chamando um construtor. Uma propriedade com um acessador private set
pode ser modificada após a construção, mas somente na classe.
O código a seguir demonstra um init
acessador em uma propriedade implementada automaticamente:
class Person_InitExampleAutoProperty
{
public int YearOfBirth { get; init; }
}
Talvez seja necessário implementar um dos acessadores para fornecer validação de parâmetro. Você pode fazer isso usando a palavra-chave, introduzida field
como um recurso de visualização no C# 13. A field
palavra-chave acessa o campo de suporte sintetizado do compilador para essa propriedade. O exemplo a seguir mostra uma propriedade em que o acessador valida init
o intervalo do value
parâmetro"
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");
}
}
}
Importante
A field
palavra-chave é um recurso de visualização no C# 13. Você deve estar usando o .NET 9 e definir seu <LangVersion>
elemento como preview
no arquivo de projeto para usar a field
palavra-chave contextual.
Você deve ter cuidado ao usar o recurso de field
palavra-chave em uma classe que tenha um campo chamado field
. A nova field
palavra-chave sombreia um campo nomeado field
no escopo de um acessador de propriedade. Você pode alterar o nome da field
variável ou usar o @
token para fazer referência ao field
identificador como @field
. Você pode saber mais lendo a especificação do recurso para a field
palavra-chave.
O acessador init
pode ser usado como membro apto para expressão. Exemplo:
class Person_InitExampleExpressionBodied
{
private int _yearOfBirth;
public int YearOfBirth
{
get => _yearOfBirth;
init => _yearOfBirth = value;
}
}
O exemplo a seguir define um acessador get
e um acessador init
para uma propriedade chamada YearOfBirth
. Ela usa um campo particular chamado _yearOfBirth
para dar suporte ao valor da propriedade.
class Person_InitExample
{
private int _yearOfBirth;
public int YearOfBirth
{
get { return _yearOfBirth; }
init { _yearOfBirth = value; }
}
}
Um acessador init
não força os chamadores a definir a propriedade. Em vez disso, permite que os chamadores usem um inicializador de objeto, proibindo modificações posteriores. Você pode adicionar o modificador required
para forçar os chamadores a definir uma propriedade. O exemplo a seguir mostra uma propriedade init
somente com um tipo de valor anulável como seu campo de apoio. Se um chamador não inicializar a YearOfBirth
propriedade, essa propriedade terá o valor padrão null
:
class Person_InitExampleNullability
{
private int? _yearOfBirth;
public int? YearOfBirth
{
get => _yearOfBirth;
init => _yearOfBirth = value;
}
}
Para forçar os chamadores a definir um valor inicial não nulo, adicione o modificador required
, conforme mostrado no exemplo a seguir:
class Person_InitExampleNonNull
{
private int _yearOfBirth;
public required int YearOfBirth
{
get => _yearOfBirth;
init => _yearOfBirth = value;
}
}
O exemplo a seguir mostra a distinção entre uma propriedade private set
, somente leitura e init
. Tanto a versão de conjunto privado quanto a versão somente leitura exigem que os chamadores usem o construtor adicionado para definir a propriedade name. A versão private set
permite que uma pessoa altere seu nome depois que a instância for criada. A versão init
não exige um construtor. Os chamadores podem inicializar as propriedades usando um inicializador de objeto:
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" };
Especificação da linguagem C#
Para obter mais informações, consulte a Especificação da linguagem C#. A especificação da linguagem é a fonte definitiva para a sintaxe e o uso de C#.