Dela via


Nyckelordet init (C#-referens)

Nyckelordet init definierar en accessor-metod i en egenskap eller indexerare. En init-only-setter tilldelar ett värde till egenskapen eller indexerarelementet endast under objektkonstruktionen. En init framtvingar oföränderlighet, så att det inte kan ändras när objektet har initierats. En init accessor gör det möjligt för anropande kod att använda en objektinitierare för att ange det ursprungliga värdet. Däremot måste en automatiskt implementerad egenskap med endast en get setter initieras genom att anropa en konstruktor. En egenskap med en private set accessor kan ändras efter konstruktionen, men endast i klassen.

Följande kod visar en init accessor i en automatiskt implementerad egenskap:

class Person_InitExampleAutoProperty
{
    public int YearOfBirth { get; init; }
}

Du kan behöva implementera en av åtkomsterna för att tillhandahålla parameterverifiering. Du kan göra det med hjälp av nyckelordet field , som introducerades som en förhandsversionsfunktion i C# 13. Nyckelordet field kommer åt det kompilatorsyntetiserade bakgrundsfältet för den egenskapen. I följande exempel visas en egenskap där init accessorn validerar parameterns value intervall"

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");
        }
    }
}

Viktigt!

Nyckelordet field är en förhandsgranskningsfunktion i C# 13. Du måste använda .NET 9 och ange <LangVersion> elementet till preview i projektfilen för att kunna använda det kontextuella nyckelordet field .

Du bör vara försiktig med att använda nyckelordsfunktionen field i en klass som har ett fält med namnet field. Det nya field nyckelordet skuggar ett fält med namnet field i omfånget för en egenskapsåtkomst. Du kan antingen ändra namnet på variabeln field eller använda @ token för att referera till identifieraren field som @field. Du kan läsa mer genom att läsa funktionsspecifikationen för nyckelordetfield.

Accessorn init kan användas som en uttrycksfyllig medlem. Exempel:

class Person_InitExampleExpressionBodied
{
    private int _yearOfBirth;

    public int YearOfBirth
    {
        get => _yearOfBirth;
        init => _yearOfBirth = value;
    }
}

I följande exempel definieras både en get och en init accessor för en egenskap med namnet YearOfBirth. Det använder ett privat fält med namnet _yearOfBirth för att stödja egenskapsvärdet.

class Person_InitExample
{
     private int _yearOfBirth;

     public int YearOfBirth
     {
         get { return _yearOfBirth; }
         init { _yearOfBirth = value; }
     }
}

En init accessor tvingar inte anropare att ange egenskapen. I stället kan anropare använda en objektinitierare samtidigt som senare ändringar inte tillåts. Du kan lägga till required modifieraren för att tvinga anropare att ange en egenskap. I följande exempel visas en init enda egenskap med en nullbar värdetyp som bakgrundsfält. Om en anropare inte initierar egenskapen har den YearOfBirth egenskapen standardvärdet null :

class Person_InitExampleNullability
{
    private int? _yearOfBirth;

    public int? YearOfBirth
    {
        get => _yearOfBirth;
        init => _yearOfBirth = value;
    }
}

Om du vill tvinga anropare att ange ett initialt värde som inte är null lägger du till required modifieraren, som du ser i följande exempel:

class Person_InitExampleNonNull
{
    private int _yearOfBirth;

    public required int YearOfBirth
    {
        get => _yearOfBirth;
        init => _yearOfBirth = value;
    }
}

I följande exempel visas skillnaden mellan en private set, skrivskyddad och init egenskap. Både den privata uppsättningens version och den skrivskyddade versionen kräver att anropare använder den tillagda konstruktorn för att ange namnegenskapen. Med private set versionen kan en person ändra sitt namn när instansen har konstruerats. Versionen init kräver ingen konstruktor. Anropare kan initiera egenskaperna med hjälp av en objektinitierare:

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" };

Språkspecifikation för C#

Mer information finns i C#-språkspecifikationen. Språkspecifikationen är den slutgiltiga källan för C#-syntax och -användning.

Se även