Megosztás a következőn keresztül:


Tulajdonságok (C# programozási útmutató)

A tulajdonság olyan tag, amely rugalmas mechanizmust biztosít egy adatmező értékének olvasására, írására vagy kiszámítására. A tulajdonságok nyilvános adattagokként jelennek meg, de speciális, kiegészítőnek nevezett módszerekként vannak implementálva. Ez a funkció lehetővé teszi, hogy a hívók könnyen hozzáférjenek az adatokhoz, és továbbra is elősegítik az adatbiztonságot és a rugalmasságot. A tulajdonságok szintaxisa a mezők természetes kiterjesztése. A mező meghatározza a tárolási helyet:

public class Person
{
    public string? FirstName;

    // Omitted for brevity.
}

Automatikusan implementált tulajdonságok

A tulajdonságdefiníciók olyan deklarációkat tartalmaznak egy és get egy set tartozékhoz, amely lekéri és hozzárendeli a tulajdonság értékét:

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

    // Omitted for brevity.
}

Az előző példa egy automatikusan implementált tulajdonságot mutat be. A fordító létrehoz egy rejtett háttérmezőt a tulajdonsághoz. A fordító emellett implementálja a tartozékok és get a tartozékok törzsét set is. A rendszer minden attribútumot alkalmaz az automatikusan implementált tulajdonságra. Az attribútumot a fordító által létrehozott háttérmezőre alkalmazhatja az attribútum címkéjének field: megadásával.

A tulajdonságot az alapértelmezett értéken kívüli értékre inicializálhatja úgy, hogy a tulajdonság záró zárójele után beállít egy értéket. Előfordulhat, hogy a tulajdonság kezdeti értékét FirstName szeretné üres sztring helyett nullüres sztringként használni. Ezt a következő kódban látható módon kell megadnia:

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

    // Omitted for brevity.
}

Mező által támogatott tulajdonságok

A C# 13-ban érvényesítési vagy egyéb logikát adhat hozzá egy tulajdonsághoz a kulcsszó előnézeti field funkciójával. A field kulcsszó hozzáfér a fordító egy tulajdonsághoz tartozó szintetizált háttérmezőhöz. Lehetővé teszi a tulajdonságkiegészítések írását anélkül, hogy külön háttérmezőt deklarálhat volna.

public class Person
{
    public string? FirstName 
    { 
        get;
        set => field = value.Trim(); 
    }

    // Omitted for brevity.
}

Fontos

A field kulcsszó egy előzetes verziójú funkció a C# 13-ban. A környezetfüggő kulcsszó használatához a .NET 9-et kell használnia, és be kell állítania <LangVersion> az elemet preview a field projektfájlban.

Körültekintően használja a field kulcsszó funkciót egy olyan osztályban, amelynek neve fieldegy mező. Az új field kulcsszó árnyékot ad egy tulajdonság-tartozék hatókörében elnevezett field mezőnek. Módosíthatja field a változó nevét, vagy a @ jogkivonat használatával hivatkozhat az field azonosítóra @field. További információkért olvassa el a kulcsszó funkciós specifikációjátfield.

Szükséges tulajdonságok

Az előző példa lehetővé teszi, hogy a hívó a tulajdonság beállítása nélkül hozzon létre egy Person alapértelmezett konstruktort FirstName . A tulajdonság típusa null értékű sztringre módosult. A C# 11-től kezdve megkövetelheti a hívóktól, hogy állítsanak be egy tulajdonságot:

public class Person
{
    public Person() { }

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

    public required string FirstName { get; init; }

    // Omitted for brevity.
}

Az előző kód két módosítást hajt végre az Person osztályon. Először is a FirstName tulajdonságdeklaráció tartalmazza a required módosítót. Ez azt jelenti, hogy az újat Person létrehozó kódoknak objektum inicializálóval kell beállítaniuk ezt a tulajdonságot. Másodszor, a paramétert firstName használó konstruktor rendelkezik az System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute attribútummal. Ez az attribútum tájékoztatja a fordítót, hogy ez a konstruktor minden. A konstruktort használó hívóknak nem kell objektum inicializálóval beállítaniuk required a tulajdonságokat.

Fontos

Ne tévessze össze required a nem null értékűvel. A tulajdonság beállítása required érvényes a következőre null : vagy default. Ha a típus nem null értékű, például string ezekben a példákban, a fordító figyelmeztetést ad ki.

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

Kifejezéstörzs-definíciók

A tulajdonságkiegészítők gyakran egysoros utasításokból állnak. A tartozék egy kifejezés eredményét rendeli hozzá vagy adja vissza. Ezeket a tulajdonságokat kifejezéssel rendelkező tagokként implementálhatja. A kifejezés törzsdefiníciói a => jogkivonatból állnak, amelyet a tulajdonsághoz hozzárendelni vagy lekérni kívánt kifejezés követ.

Az írásvédett tulajdonságok kifejezés-testes tagként implementálhatják a get tartozékot. Az alábbi példa az írásvédett Name tulajdonságot kifejezés-testes tagként implementálja:

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.
}

A Name tulajdonság egy számított tulajdonság. Nincs háttérmező a következőhöz Name: . A tulajdonság minden alkalommal kiszámítja.

Hozzáférés-vezérlés

Az előző példák olvasási/írási tulajdonságokat mutattak. Írásvédett tulajdonságokat is létrehozhat, vagy különböző kisegítő lehetőségeket biztosíthat a készlet számára, és tartozékokat szerezhet be. Tegyük fel, hogy az Person osztálynak csak a tulajdonság értékének módosítását kell engedélyeznie az FirstName osztály más metódusaitól. A következő helyett a következő helyett adhat hozzáférést a beállított tartozéknak privateinternalpublic:

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

    // Omitted for brevity.
}

A FirstName tulajdonság bármely kódból olvasható, de csak az Person osztály kódjából rendelhető hozzá.

Hozzáadhat bármilyen korlátozó hozzáférés-módosító elemet a készlethez, vagy beszerezheti a tartozékokat. Az egyes tartozékokon a hozzáférés-módosítónak szigorúbbnak kell lennie, mint a tulajdonsághoz való hozzáférés. Az előző kód azért jogi, mert a FirstName tulajdonság az public, de a készlet tartozéka .private Nem deklarálhat tulajdonságot private tartozékokkal public . A tulajdonságdeklarációk deklarálhatók protectedinternalprotected internal, vagy akár .private

A tartozékokhoz set két speciális hozzáférési módosító van:

  • A set tartozék rendelkezhet init hozzáférés-módosítóként. Ez a set tartozék csak objektum inicializálóból vagy a típus konstruktoraiból hívható meg. Szigorúbb, mint private a set tartozékon.
  • Az automatikusan megvalósított tulajdonságok kiegészítő nélkül deklarálhatnak egy get tartozékot set . Ebben az esetben a fordító lehetővé teszi, hogy a set tartozék csak a típus konstruktoraiból legyen meghívva. Ez szigorúbb, mint a init tartozékon lévő set tartozék.

Módosítsa az osztályt az Person alábbiak szerint:

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

    public string FirstName { get; }

    // Omitted for brevity.
}

Az előző példa megköveteli, hogy a hívók a paramétert tartalmazó konstruktort FirstName használják. A hívók nem használhatnak objektum inicializálókat , hogy értéket rendeljenek a tulajdonsághoz. Az inicializálók támogatásához a set tartozékot kiegészítőként init is használhatja, ahogyan az a következő kódban is látható:

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

    public string? FirstName { get; init; }

    // Omitted for brevity.
}

Ezeket a módosítókat gyakran használják a módosítóval a required megfelelő inicializálás kényszerítéséhez.

Tulajdonságok háttérmezőkkel

A számítási tulajdonság fogalmát kombinálhatja egy privát mezővel, és létrehozhat egy gyorsítótárazott kiértékelt tulajdonságot. Frissítse például a FullName tulajdonságot úgy, hogy a sztringformázás az első hozzáférésen történjen:

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

Ez a megvalósítás azért működik, mert a tulajdonságok és FirstName a LastName tulajdonságok olvashatók. A felhasználók módosíthatják a nevüket. A FirstName tartozékok engedélyezésére LastName szolgáló tulajdonságok és set tulajdonságok frissítéséhez érvénytelenítenie kell a gyorsítótárazott értékeket.fullName Módosítsa a tulajdonság és set a FirstNameLastName tulajdonság tartozékait, hogy a fullName mező újra ki legyen számítva:

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

Ez a végleges verzió csak szükség esetén értékeli ki a FullName tulajdonságot. Ha érvényes, a korábban számított verziót használja a rendszer. Ellenkező esetben a számítás frissíti a gyorsítótárazott értéket. Az osztályt használó fejlesztőknek nem kell tudniuk az implementáció részleteit. A belső módosítások egyike sem befolyásolja a Person objektum használatát.

A C# 13-tól partial kezdve létrehozhat tulajdonságokat az osztályokban partial . A tulajdonság implementálási partial deklarációja nem lehet automatikusan implementált tulajdonság. Az automatikusan implementált tulajdonság szintaxisa megegyezik a részleges tulajdonságdeklaráció deklarálásával.

Tulajdonságok

A tulajdonságok egy osztály vagy objektum intelligens mezőinek egy formája. Az objektumon kívülről az objektum mezőiként jelennek meg. A tulajdonságok azonban a C#-funkciók teljes palettáján implementálhatók. Érvényesítést, különböző akadálymentességet, lusta értékelést vagy bármilyen követelményt biztosíthat a forgatókönyvek számára.

  • Az egyéni kiegészítő kódot nem igénylő egyszerű tulajdonságok kifejezéstörzs-definíciókként vagy automatikusan implementált tulajdonságokként is implementálhatók.
  • A tulajdonságok lehetővé teszik az osztály számára, hogy nyilvánosan megjelenítse az értékek lekérésének és beállításának módját, miközben elrejti a megvalósítási vagy ellenőrzési kódot.
  • A beolvasási tulajdonság tartozéka a tulajdonságérték visszaadására szolgál, a megadott tulajdonság-tartozék pedig egy új érték hozzárendelésére szolgál. Az inicializálási tulajdonság tartozékai csak az objektumépítés során rendelhetők hozzá új értékekhez. Ezek a tartozékok különböző hozzáférési szintekkel rendelkezhetnek. További információ: A kiegészítő akadálymentesség korlátozása.
  • Az érték kulcsszó a hozzárendelt érték set meghatározására init szolgál.
  • A tulajdonságok lehetnek írásvédettek (tartozékuk és get tartozékuk isset), írásvédett (tartozékuk vanget, de nincs set tartozékuk), vagy írásvédett (tartozékuk vanset, de tartozékuk nincsget). A csak írási tulajdonságok ritkák.

C# nyelvi specifikáció

További információ: Tulajdonságok a C# nyelvi specifikációjában. A nyelvi specifikáció a C#-szintaxis és -használat végleges forrása.

Lásd még