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ó olyan deklarációkat tartalmaz egy get és egy set hozzáférőhöz, 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 get és set elérők törzsét 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 FirstName tulajdonság kezdeti értékét üres sztringként szeretné megadni a null helyett. 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# 14-ben érvényesítési vagy egyéb logikát adhat hozzá egy tulajdonsághoz a field kulcsszó használatával. A field kulcsszó hozzáfér egy tulajdonság fordító által szintetizált háttérmezőjéhez. 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.
}

Szükséges tulajdonságok

Az előző példa lehetővé teszi, hogy a hívó alapértelmezett konstruktor használatával hozzon létre egy Person, anélkül hogy beállítaná a FirstName tulajdonságot. A tulajdonság típusa null értékű sztringre módosult. A hívóktól megkövetelheti egy tulajdonság beállítását:

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 beállítja az összes tagot. 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 required tulajdonság beállítása érvényes null vagy default értékekre. 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 hozzáférők egy kifejezés eredményét rendelik hozzá vagy adják vissza. Ezeket a tulajdonságokat kifejezés-alapú 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ő hozzáférési szinteket adhat meg a set és get metódusokhoz. 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 set hozzáférési szintje lehetne private a internal vagy public helyett.

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 megfelelő, mert a FirstName tulajdonság az public, de a setter private. Nem deklarálhat egy private tulajdonságot egy public hozzáférővel. A tulajdonságdeklarációk deklarálhatók protectedinternalprotected internal, vagy akár .private

Az set hozzáférők számára 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ág deklarálhat egy get hozzáférőt set hozzáférő nélkül. Ebben az esetben a fordító lehetővé teszi, hogy a set tartozék csak a típus konstruktoraiból legyen meghívva. Ez korlátozóbb, mint a init hozzáférési elem a set hozzáférési elemen.

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. A kezdők támogatásához a set elérési mód helyére init elérési módot tehet, amint az a következő kódban 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 a required módosítóval együtt használják a megfelelő inicializálás kényszerítéséhez.

Tulajdonságok háttérmezőkkel

A számított 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 FirstName és LastName tulajdonságok csak olvashatók. A felhasználók módosíthatják a nevüket. A FirstName és LastName tulajdonságok frissítéséhez, hogy engedélyezzék a set elérést, érvénytelenítenie kell a fullName gyorsítótárazott értékét. Módosítja a set hozzáférési metódusait a FirstName és a LastName tulajdonságoknak, hogy a fullName mező újra kiszámítódjon:

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-ban bevezetve létrehozhat partial tulajdonságokat az partial osztályokban. 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. Biztosíthat érvényesítést, különböző hozzáférhetőséget, halasztott értékelést, vagy az eseteidhez bármilyen követelményt.

  • 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ó arra szolgál, hogy meghatározza, milyen értéket rendel hozzá a set vagy a init hozzáférő.
  • A tulajdonságok lehetnek olvasás-írás (van get és set hozzáférőjük), csak olvashatók (van get hozzáférőjük, de nincs set hozzáférőjük), vagy csak írhatók (van set hozzáférőjük, de nincs get hozzáférőjük). 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