Share via


Eigenschappen (C#-programmeerhandleiding)

Een eigenschap is een lid dat een flexibel mechanisme biedt voor het lezen, schrijven of berekenen van de waarde van een gegevensveld. Eigenschappen worden weergegeven als leden van openbare gegevens, maar ze worden geïmplementeerd als speciale methoden die accessors worden genoemd. Met deze functie kunnen bellers eenvoudig toegang krijgen tot gegevens en kunnen ze nog steeds de veiligheid en flexibiliteit van gegevens bevorderen. De syntaxis voor eigenschappen is een natuurlijke uitbreiding op velden. Een veld definieert een opslaglocatie:

public class Person
{
    public string? FirstName;

    // Omitted for brevity.
}

Eigenschappen die automatisch zijn geïmplementeerd

Een eigenschapsdefinitie bevat declaraties voor een get en set accessor die de waarde van die eigenschap ophaalt en toewijst:

public class Person
{
    public string? FirstName { get; set; }

    // Omitted for brevity.
}

In het voorgaande voorbeeld ziet u een eigenschap die automatisch is geïmplementeerd. De compiler genereert een verborgen back-upveld voor de eigenschap. De compiler implementeert ook de hoofdtekst van de get en set accessors. Alle kenmerken worden toegepast op de eigenschap die automatisch is geïmplementeerd. U kunt het kenmerk toepassen op het door de compiler gegenereerde backingveld door de field: tag op te geven op het kenmerk.

U kunt een eigenschap initialiseren op een andere waarde dan de standaardwaarde door een waarde in te stellen na de accolade sluiten voor de eigenschap. Mogelijk geeft u de voorkeur aan de oorspronkelijke waarde voor de FirstName eigenschap als de lege tekenreeks in plaats nullvan . U geeft dit op zoals wordt weergegeven in de volgende code:

public class Person
{
    public string FirstName { get; set; } = string.Empty;

    // Omitted for brevity.
}

Toegangsbeheer

In de voorgaande voorbeelden zijn lees-/schrijfeigenschappen weergegeven. U kunt ook alleen-lezeneigenschappen maken of andere toegankelijkheid geven aan de set en accessors ophalen. Stel dat uw Person klasse alleen het wijzigen van de waarde van de FirstName eigenschap van andere methoden in die klasse moet inschakelen. U kunt de toegankelijkheid van de settoegangsfunctie private geven in plaats van public:

public class Person
{
    public string? FirstName { get; private set; }

    // Omitted for brevity.
}

De FirstName eigenschap kan worden gelezen uit elke code, maar kan alleen worden toegewezen vanuit code in de Person klasse.

U kunt elke beperkende toegangsaanpassing toevoegen aan de set of get accessors. Een toegangsaanpassing voor een afzonderlijke toegangsfunctie moet meer beperkend zijn dan de toegang van de eigenschap. De voorgaande code is legaal omdat de FirstName eigenschap is public, maar de set accessor is private. U kunt een private eigenschap met een public accessor niet declareren. Eigenschapsdeclaraties kunnen ook worden gedeclareerd protected, internal, protected internalof zelfs private.

Er zijn twee speciale toegangsaanpassingen voor set accessors:

  • Een set toegangsfunctie kan een toegangsaanpassing hebben init . Deze set accessor kan alleen worden aangeroepen vanuit een object-initialisatiefunctie of de constructors van het type. Het is meer beperkend dan private de set accessor.
  • Een automatisch geïmplementeerde eigenschap kan een get accessor declareren zonder set toegangsrechten. In dat geval staat de compiler toe dat de set accessor alleen kan worden aangeroepen vanuit de constructors van het type. Het is meer beperkend dan de init accessor op de set toegangsrechten.

Wijzig de Person klasse als volgt:

public class Person
{
    public Person(string firstName) => FirstName = firstName;

    public string FirstName { get; }

    // Omitted for brevity.
}

In het voorgaande voorbeeld moeten bellers de constructor gebruiken die de FirstName parameter bevat. Bellers kunnen geen object-initializers gebruiken om een waarde toe te wijzen aan de eigenschap. Als u initialisatieprogramma's wilt ondersteunen, kunt u de set accessor een init toegangsfunctie maken, zoals wordt weergegeven in de volgende code:

public class Person
{
    public Person() { }
    public Person(string firstName) => FirstName = firstName;

    public string? FirstName { get; init; }

    // Omitted for brevity.
}

Deze modifiers worden vaak gebruikt met de required modifier om de juiste initialisatie af te dwingen.

Vereiste eigenschappen

In het voorgaande voorbeeld kan een aanroeper een Person maken met behulp van de standaardconstructor, zonder de FirstName eigenschap in te stellen. Het eigenschapstype is gewijzigd in een tekenreeks die null kan worden gebruikt. Vanaf C# 11 kunt u vereisen dat bellers een eigenschap instellen:

public class Person
{
    public Person() { }

    [SetsRequiredMembers]
    public Person(string firstName) => FirstName = firstName;

    public required string FirstName { get; init; }

    // Omitted for brevity.
}

De voorgaande code brengt twee wijzigingen aan in de Person klasse. Eerst bevat de FirstName eigenschapsdeclaratie de required wijzigingsfunctie. Dit betekent dat elke code die een nieuwe Person maakt, deze eigenschap moet instellen met behulp van een object-initialisatiefunctie. Ten tweede heeft de constructor die een firstName parameter gebruikt het System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute kenmerk. Dit kenmerk informeert de compiler dat met deze constructor alle leden worden required ingesteld. Bellers die deze constructor gebruiken, zijn niet vereist om eigenschappen in te stellen required met een object-initialisatiefunctie.

Belangrijk

Verwar required niet met niet-nullable. Het is geldig om een required eigenschap in te stellen op null of default. Als het type niet null-compatibel is, zoals string in deze voorbeelden, geeft de compiler een waarschuwing.

var aPerson = new Person("John");
aPerson = new Person{ FirstName = "John"};
// Error CS9035: Required member `Person.FirstName` must be set:
//aPerson2 = new Person();

Hoofdtekstdefinities voor expressies

Eigenschapstoegangsors bestaan vaak uit instructies met één regel. De accessors wijzen het resultaat van een expressie toe of retourneren. U kunt deze eigenschappen implementeren als leden met expressies. Hoofdtekstdefinities van expressies bestaan uit het => token, gevolgd door de expressie die moet worden toegewezen aan of opgehaald uit de eigenschap.

Eigenschappen met het kenmerk Alleen-lezen kunnen de get toegangsfunctie implementeren als een expressie-lid. In het volgende voorbeeld wordt de eigenschap Alleen-lezen Name geïmplementeerd als een expressielid:

public class Person
{
    public Person() { }

    [SetsRequiredMembers]
    public Person(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }

    public required string FirstName { get; init; }
    public required string LastName { get; init; }

    public string Name => $"{FirstName} {LastName}";

    // Omitted for brevity.
}

De Name eigenschap is een berekende eigenschap. Er is geen backingveld voor Name. De eigenschap berekent deze elke keer.

Eigenschappen met back-upvelden

U kunt het concept van een berekende eigenschap combineren met een privéveld en een geëvalueerde eigenschap in de cache maken. Werk bijvoorbeeld de FullName eigenschap bij zodat de tekenreeksopmaak op de eerste toegang plaatsvindt:

public class Person
{
    public Person() { }

    [SetsRequiredMembers]
    public Person(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }

    public required string FirstName { get; init; }
    public required string LastName { get; init; }

    private string? _fullName;
    public string FullName
    {
        get
        {
            if (_fullName is null)
                _fullName = $"{FirstName} {LastName}";
            return _fullName;
        }
    }
}

Deze implementatie werkt omdat de FirstName eigenschappen en LastName eigenschappen alleen-lezen zijn. Mensen kunnen hun naam wijzigen. Als u de FirstName eigenschappen LastName bijwerkt om accessors toe te staan set , moet u een waarde in de cache ongeldig maken voor fullName. U wijzigt de set toegangsrechten van de FirstName en LastName eigenschap zodat het fullName veld opnieuw wordt berekend:

public class Person
{
    private string? _firstName;
    public string? FirstName
    {
        get => _firstName;
        set
        {
            _firstName = value;
            _fullName = null;
        }
    }

    private string? _lastName;
    public string? LastName
    {
        get => _lastName;
        set
        {
            _lastName = value;
            _fullName = null;
        }
    }

    private string? _fullName;
    public string FullName
    {
        get
        {
            if (_fullName is null)
                _fullName = $"{FirstName} {LastName}";
            return _fullName;
        }
    }
}

Deze definitieve versie evalueert de FullName eigenschap alleen wanneer dat nodig is. De eerder berekende versie wordt gebruikt indien geldig. Anders werkt de berekening de waarde in de cache bij. Ontwikkelaars die deze klasse gebruiken, hoeven de details van de implementatie niet te weten. Geen van deze interne wijzigingen heeft invloed op het gebruik van het object Person.

Vanaf C# 13 kunt u eigenschappen maken partial in partial klassen. De implementatiedeclaratie voor een partial eigenschap kan geen automatisch geïmplementeerde eigenschap zijn. Een eigenschap die automatisch is geïmplementeerd, gebruikt dezelfde syntaxis als een declaratie van gedeeltelijke eigenschappen.

Eigenschappen

Eigenschappen zijn een vorm van slimme velden in een klasse of object. Van buiten het object worden ze weergegeven als velden in het object. Eigenschappen kunnen echter worden geïmplementeerd met behulp van het volledige palet van C#-functionaliteit. U kunt validatie, verschillende toegankelijkheid, luie evaluatie of eventuele vereisten bieden die uw scenario's nodig hebben.

  • Eenvoudige eigenschappen waarvoor geen aangepaste toegangscode is vereist, kunnen worden geïmplementeerd als hoofdtekstdefinities van expressies of als automatisch geïmplementeerde eigenschappen.
  • Met eigenschappen kan een klasse een openbare manier weergeven om waarden op te halen en in te stellen, terwijl implementatie- of verificatiecode wordt verborgen.
  • Een get property accessor wordt gebruikt om de eigenschapswaarde te retourneren en er wordt een set eigenschapstoegangsfunctie gebruikt om een nieuwe waarde toe te wijzen. Een init-eigenschapstoegangsobject wordt gebruikt om alleen een nieuwe waarde toe te wijzen tijdens het bouwen van objecten. Deze accessors kunnen verschillende toegangsniveaus hebben. Zie Toegankelijkheid van accessor beperken voor meer informatie.
  • Het trefwoord waarde wordt gebruikt om de waarde te definiëren die de set of init accessor toewijst.
  • Eigenschappen kunnen lezen/schrijven zijn (ze hebben zowel een get als een set accessor), alleen-lezen (ze hebben een get toegangsbeheerprogramma maar geen set toegangsrechten), of alleen-schrijven (ze hebben een set accessor, maar geen get toegangsbeheerprogramma). Eigenschappen met alleen-schrijven zijn zeldzaam.

C#-taalspecificatie

Zie Eigenschappen in de C#-taalspecificatie voor meer informatie. De taalspecificatie is de definitieve bron voor de C#-syntaxis en het gebruik.

Zie ook