A C# 13 újdonságai

A C# 13 az alábbi új funkciókat tartalmazza. Ezeket a funkciókat a legújabb Visual Studio 2022 verzióval vagy a .NET 9 SDK használatával próbálhatja ki.

A Visual Studio 17.12-től kezdődően a C# 13 előzetes verzióként tartalmazza a field környezeti kulcsszót.

A C# 13 támogatott .NET 9. További információért lásd a C# nyelv verziószámozása.

A legújabb .NET 9 SDK-t a .NET letöltési oldaláról töltheti le. Letöltheti Visual Studio 2022is, amely tartalmazza a .NET 9 SDK-t is.

A C# 13-ban bevezetett kompatibilitástörő módosításokat a kompatibilitástörő változásokrólszóló cikkünkben találja.

Jegyzet

Szeretnénk visszajelzést küldeni ezekről a funkciókról. Ha problémákat talál az új funkciók bármelyikével kapcsolatban, hozzon létre egy új problémát, a dotnet/roslyn adattárban.

params gyűjtemények

A params módosító nem korlátozódik tömbtípusokra. Mostantól bármilyen felismert gyűjteménytípussal használhatja a params-t, beleértve a System.Span<T>-t, a System.ReadOnlySpan<T>-t, valamint azokat a típusokat, amelyek megvalósítják a System.Collections.Generic.IEnumerable<T>-at és rendelkeznek Add metódussal. A betontípusok mellett a System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.Generic.IReadOnlyList<T>, System.Collections.Generic.ICollection<T>és System.Collections.Generic.IList<T> interfészek is használhatók.

Felülettípus használata esetén a fordító szintetizálja a megadott argumentumok tárterületét. További információt a params gyűjteményekfunkciós specifikációjában talál.

A metódusdeklarációk például params paraméterekként deklarálhatják a spanokat:

public void Concat<T>(params ReadOnlySpan<T> items)
{
    for (int i = 0; i < items.Length; i++)
    {
        Console.Write(items[i]);
        Console.Write(" ");
    }
    Console.WriteLine();
}

Új zárolási objektum

A .NET 9 futtatókörnyezet új típust tartalmaz a szálszinkronizáláshoz, a System.Threading.Lock típushoz. Ez a típus jobb szálszinkronizálást biztosít az API-jával. A Lock.EnterScope() metódus kizárólagos hatókört ad meg. Az a ref struct, amelyet visszaadtak, támogatja a Dispose() mintát, hogy kiléphessen a kizárólagos hatókörből.

A C# lock utasítás felismeri, hogy a zárolás célja egy Lock objektum. Ha igen, akkor a frissített API-t használja, nem pedig a hagyományos API-t System.Threading.Monitor. A fordító felismeri azt is, ha egy Lock objektumot egy másik típusra konvertál, és létrejön a Monitor alapú kód. Az új zárolási objektumfunkcióspecifikációjában olvashat bővebben.

Ez a funkció lehetővé teszi az új könyvtártípus előnyeinek kihasználását azáltal, hogy módosítja a lockobjektum típusát. Más kódot nem kell módosítani.

Új menekülési sorozat

A \e használható karakterkonstanskéntESCAPE unicode U+001B. Korábban a \u001b-t vagy a \x1b-et használtad. A \x1b használata nem ajánlott, mert ha az 1b követő következő karakterek érvényes hexadecimális számjegyek voltak, ezek a karakterek a feloldósorozat részévé váltak.

Metóduscsoport természetes típusa

Ez a funkció kis optimalizálásokat végez a metóduscsoportokat érintő túlterhelés feloldásánál. A metóduscsoport egy metódus, és minden túlterhelés azonos nevű. Az előző viselkedés az volt, hogy a fordító egy metóduscsoporthoz a jelölt metódusok teljes készletét hozta létre. Ha természetes típusra volt szükség, a természetes típust a jelölt módszerek teljes készletéből határozták meg.

Az új viselkedés, hogy az egyes hatókörökben le kell metszeni a jelölt metódusokat, és el kell távolítani azokat, amelyek nem alkalmazhatók. Az eltávolított metódusok általában olyan általános metódusok, amelyek nem megfelelő aritásúak, vagy amelyek nem felelnek meg a feltételeknek. A folyamat csak akkor folytatódik a következő külső hatókörbe, ha nem talál jelölt metódusokat. Ez a folyamat jobban követi az általános algoritmust a túlterhelés feloldásához. Ha egy adott hatókörben található összes jelölt metódus nem egyezik, a metóduscsoport nem rendelkezik természetes típussal.

A javaslat specifikációjábanváltozások részleteit olvashatja el.

Implicit index hozzáférés

Az implicit "from the end" indexoperátor ^mostantól engedélyezve van egy objektum inicializáló kifejezésében egydimenziós gyűjteményekhez. Most például inicializálhat egy egydimenziós tömböt egy objektum inicializáló használatával, ahogyan az az alábbi kódban látható:

public class TimerRemaining
{
    public int[] buffer { get; set; } = new int[10];
}

var countdown = new TimerRemaining()
{
    buffer =
    {
        [^1] = 0,
        [^2] = 1,
        [^3] = 2,
        [^4] = 3,
        [^5] = 4,
        [^6] = 5,
        [^7] = 6,
        [^8] = 7,
        [^9] = 8,
        [^10] = 9
    }
};

A TimerRemaining osztály egy 10 hosszúságúra inicializált buffer tömböt tartalmaz. Az előző példa a "from the end" indexoperátor (^) használatával rendel értékeket ehhez a tömbhöz, amely 9-ről 0-ra visszaszámlálható tömböt hoz létre.

A C# 13 előtti verziókban a ^ operátor nem használható objektum-inicializálóban. Az elemeket elölről kell indexelnie.

ref és unsafe iterátorokban és async metódusokban

Ez a funkció és a következő két funkció lehetővé teszi ref struct típusok számára az új szerkezetek használatát. Ezeket a funkciókat csak akkor fogja használni, hacsak nem ír saját ref struct típusokat. Valószínűbb, hogy közvetett előnyt lát, és System.Span<T>System.ReadOnlySpan<T> több funkciót kap.

A C# 13 előtt az iterátor metódusok (yield returnhasználó metódusok) és async metódusok nem deklarálhatták a helyi ref változókat, és unsafe környezetük sem volt.

A C# 13-ban async metódusok deklarálhatnak ref helyi változókat vagy ref struct típusú helyi változókat. Ezek a változók azonban nem érhetők el await határokon keresztül. Egyik sem érhető el yield return határon keresztül.

Ez a enyhített korlátozás lehetővé teszi, hogy a fordító több helyen is biztonságosan használhassa ref helyi változókat és ref struct típusokat. Ezekben a módszerekben biztonságosan használhat olyan típusokat, mint a System.ReadOnlySpan<T>. A fordító megmondja neked, ha megszegi a biztonsági szabályokat.

Ugyanígy a C# 13 lehetővé teszi unsafe környezetek iterálási metódusokban való használatát. Azonban minden yield return és yield break utasításnak biztonságos környezetben kell lennie.

allows ref struct

A C# 13 előtt ref struct típusok nem deklarálhatók általános típus vagy metódus típusargumentumaként. Az általános típusdeklarációk mostantól kényszermentesség-gátlót adhatnak hozzá, allows ref struct. Ez a korlátozás azt deklarálja, hogy az adott típusparaméterhez megadott típusargumentum lehet ref struct típus. A fordító a ref biztonsági szabályokat kényszeríti ki az adott típusú paraméter összes példányára.

Deklarálhat például egy általános típust, például a következő kódot:

public class C<T> where T : allows ref struct
{
    // Use T as a ref struct:
    public void M(scoped T p)
    {
        // The parameter p must follow ref safety rules
    }
}

Ez lehetővé teszi az olyan típusok használatát, mint például a System.Span<T> és a System.ReadOnlySpan<T> általános algoritmusokkal, ahol alkalmazható. További információt a where frissítéseiben és az általános korlátozások című programozási útmutatóban talál.

ref struct felületek

A C# 13 előtt ref struct típusok nem implementálhattak interfészeket. A C# 13-tól kezdve lehetőségük van. Deklarálhatja, hogy egy ref struct típus illesztőt implementál. A ref biztonsági szabályok biztosítása érdekében azonban egy ref struct típus nem konvertálható interfésztípussá. Ez az átalakítás egy boxing konverzió, és sértheti a ref biztonságát. A ref struct explicit felületmetódus-deklarációi csak olyan típusparaméteren keresztül érhetők el, ahol az adott típusparaméter allows ref struct. Emellett ref struct típusoknak implementálniuk kell a felületen deklarált összes metódust, beleértve az alapértelmezett implementációval rendelkező metódusokat is.

További információ a ref struct típusú frissítéséről és az általános allows ref struct korlátozás hozzáadásáról.

További részleges tagok

A C# 13-ban deklarálhat partial tulajdonságokat és partial indexelőket. A részleges tulajdonságok és indexelők általában ugyanazokat a szabályokat követik, mint partial metódusok: egy deklaráló deklaráció és egy implementáló deklaráció. A két nyilatkozat aláírásának egyeznie kell. Az egyik korlátozás az, hogy nem használhat automatikus tulajdonságdeklarációt részleges tulajdonság implementálására. Azok a tulajdonságok, amelyek nem deklarálnak egy törzset, deklaráló deklarációnak minősülnek.

public partial class C
{
    // Declaring declaration
    public partial string Name { get; set; }
}

public partial class C
{
    // implementation declaration:
    private string _name;
    public partial string Name
    {
        get => _name;
        set => _name = value;
    }
}

A részleges tagokkal kapcsolatoscímű cikkben talál további információt.

Túlterhelésfeloldási prioritás

A C# 13-ban a fordító felismeri a OverloadResolutionPriorityAttribute mintát, hogy egyik túlterhelést előnyben részesítse a másikkal szemben. A kódtár-szerzők ezt az attribútumot használhatják annak biztosítására, hogy a meglévő túlterhelés helyett egy új, jobb túlterhelés legyen előnyben. Előfordulhat például, hogy egy jobb teljesítményű túlterhelést ad hozzá. Nem szeretné megszakítani a kódtárat használó meglévő kódot, de azt szeretné, hogy a felhasználók újrafordításkor frissítsenek az új verzióra. A Túlterhelésfeloldási prioritás használatával tájékoztathatja a fordítót arról, hogy melyik túlterhelést érdemes előnyben részesíteni. Előnyben részesítik a legmagasabb prioritású túlterheléseket.

Ez a funkció a könyvtárszerzők számára készült, hogy elkerüljék a kétértelműséget az új túlterhelések hozzáadásakor. A könyvtár szerzőinek óvatosan kell bánniuk ezzel az attribútummal a félreértések elkerülése érdekében.

A field kulcsszó

A field környezeti kulcsszó a C# 13-ban van előzetes verziójú funkcióként. A token field hozzáfér a fordító által szintetizált háttérmezőhöz egy tulajdonság hozzáférési metódusában. Lehetővé teszi, hogy hozzáférő törzset írjon úgy, hogy nem kell explicit háttérmezőt deklarálnia a típusdeklarációban. A mező alapú tulajdonsághoz deklarálhat törzset az egyik vagy mindkét hozzáférési metódus számára.

A field funkció előzetes verziójú funkcióként jelenik meg. Szeretnénk tanulni az ön tapasztalataiból. Előfordulhat, hogy kompatibilitástörés vagy zavart okoz a kód olvasásakor azokban a típusokban, amelyek fieldnevű mezőt is tartalmaznak. Az @field kulcsszó és az azonosító közötti egyértelműsítéshez használhatja az this.field vagy field jelöléseket.

Fontos

Körültekintően használja a field kulcsszó jellemzőt egy olyan osztályban, amely fieldnevű mezőt tartalmaz. Az új field kulcsszó árnyékolást alkalmaz egy field nevű mezőn egy tulajdonságkiegészítő hatókörében. Módosíthatja a field változó nevét, vagy a @ token használatával hivatkozhat a field azonosítóra @field. Többet megtudhat, ha elolvassa a field kulcsszófunkcióspecifikációját.

Ha kipróbálja ezt a funkciót, és visszajelzést szeretne küldeni, adja hozzá a funkcióval kapcsolatos problémához, a csharplang adattárban.

Lásd még: