Udostępnij za pośrednictwem


Co nowego w języku C# 13

Język C# 13 zawiera następujące nowe funkcje. Możesz wypróbować te funkcje przy użyciu najnowszej wersji Visual Studio 2022 lub zestawu SDK platformy .NET 9:

Począwszy od programu Visual Studio 17.12, język C# 13 zawiera kontekstowe słowo kluczowe field jako funkcję w wersji zapoznawczej.

Język C# 13 jest obsługiwany w programie .NET 9. Aby uzyskać więcej informacji, zobacz wersjonowanie języka C#.

Najnowszą wersję zestawu .NET 9 SDK można pobrać ze strony pobierania .NET. Możesz również pobrać Visual Studio 2022, który zawiera zestaw SDK platformy .NET 9.

Nowe funkcje są dodawane do strony "Co nowego w języku C#", gdy są one dostępne w publicznej wersji zapoznawczej. Sekcja zestawu roboczego strony stanu funkcji roslyn ścieżki po scaleniu nadchodzących funkcji z gałęzią główną.

Wszelkie zmiany powodujące niezgodność wprowadzone w języku C# 13 można znaleźć w naszym artykule dotyczącym zmian powodujących niezgodność.

Notatka

Interesuje nas Twoja opinia na temat tych funkcji. Jeśli znajdziesz problemy z dowolną z tych nowych funkcji, utwórz nowe zgłoszenie w repozytorium dotnet/roslyn.

kolekcje params

Modyfikator params nie jest ograniczony do typów tablic. Można teraz używać params z dowolnym uznanym typem kolekcji, w tym System.Span<T>, System.ReadOnlySpan<T>i typami implementującymi System.Collections.Generic.IEnumerable<T> i posiadającymi metodę Add. Oprócz konkretnych typów interfejsy System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.Generic.IReadOnlyList<T>, System.Collections.Generic.ICollection<T>i System.Collections.Generic.IList<T> mogą być również używane.

Gdy używany jest typ interfejsu, kompilator syntetyzuje magazyn dla podanych argumentów. Więcej informacji można znaleźć w specyfikacji funkcji kolekcji params.

Na przykład deklaracje metod mogą deklarować zakresy jako parametry params:

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

Nowy obiekt blokady

Środowisko uruchomieniowe platformy .NET 9 zawiera nowy typ synchronizacji wątków, typ System.Threading.Lock. Ten typ zapewnia lepszą synchronizację wątków za pośrednictwem interfejsu API. Metoda Lock.EnterScope() wprowadza zakres wyłączny. ref struct zwrócony z niego obsługuje wzorzec Dispose(), aby zamknąć zakres wyłączny.

Instrukcja lock języka C# rozpoznaje, czy element docelowy blokady jest obiektem Lock. Jeśli tak, używa zaktualizowanego interfejsu API, a nie tradycyjnego interfejsu API przy użyciu System.Threading.Monitor. Kompilator rozpoznaje również, czy przekonwertowasz obiekt Lock na inny typ, a kod oparty na Monitor zostanie wygenerowany. Więcej informacji można znaleźć w specyfikacji funkcji dla nowy obiekt blokady.

Ta funkcja umożliwia uzyskanie korzyści z nowego typu biblioteki przez zmianę typu obiektu lock. Nie trzeba zmieniać żadnego innego kodu.

Nowa sekwencja ucieczki

Można użyć \e jako literalu znaku w sekwencji ucieczki dla znaku ESCAPE, Unicode U+001B. Wcześniej użyto \u001b lub \x1b. Użycie \x1b nie było zalecane, ponieważ jeśli następne znaki po 1b były prawidłowymi cyframi szesnastkowymi, te znaki stały się częścią sekwencji ucieczki.

Naturalny typ grupy metod

Ta funkcja dokonuje drobnych optymalizacji w zakresie rozwiązywania przeciążeń obejmujących grupy metod. grupa metod obejmuje metodę i wszystkie przeciążenia o tej samej nazwie. Poprzednie zachowanie polegało na tym, że kompilator tworzył pełny zestaw metod-kandydatów dla grupy metod. Jeśli potrzebny jest typ naturalny, typ naturalny został określony z pełnego zestawu metod kandydatów.

Nowe zachowanie polega na oczyszczeniu zestawu metod kandydatów w każdym zakresie, usuwając te metody kandydatów, które nie mają zastosowania. Zazwyczaj usunięte metody są metodami generycznymi z niewłaściwą liczbą argumentów lub ograniczeniami, które nie są spełnione. Proces jest kontynuowany do następnego zakresu zewnętrznego tylko wtedy, gdy nie znaleziono żadnych metod kandydatów. Ten proces ściślej śledzi ogólny algorytm rozpoznawania przeciążenia. Jeśli wszystkie metody kandydujące znalezione w danym zakresie nie są zgodne, grupa metod nie ma naturalnego typu.

Szczegółowe informacje o zmianach można znaleźć w specyfikacji propozycji .

Niejawny dostęp do indeksu

Niejawny operator indeksu "from the end" (od końca), ^, może być używany w wyrażeniu inicjalizatora obiektu. Można na przykład zainicjować tablicę w inicjatorze obiektu, jak pokazano w poniższym kodzie:

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

Klasa TimerRemaining zawiera tablicę buffer zainicjowaną o długości 10. Powyższy przykład przypisuje wartości do tej tablicy przy użyciu operatora indeksowania "od końca" (^), skutecznie tworząc tablicę, która odlicza od 9 do 0.

W wersjach wcześniejszych niż C# 13 operator ^ nie może być używany w inicjatorze obiektów. Należy zaindeksować elementy od początku.

ref i unsafe w iteratorach i metodach async

Następujące trzy funkcje umożliwiają typom ref struct korzystanie z nowych konstrukcji. Nie będziesz ich używać, chyba że napiszesz własne typy ref struct. Najprawdopodobniej zobaczysz korzyść pośrednią, w miarę jak System.Span<T> i System.ReadOnlySpan<T> uzyskają więcej funkcjonalności.

Przed użyciem języka C# 13 metody iteracyjne (metody korzystające z yield return) i metody async nie mogły zadeklarować zmiennych ref lokalnych ani nie mogły mieć kontekstu unsafe.

W C# 13 metody async mogą deklarować lokalne zmienne ref lub zmienne lokalne typu ref struct. Nie można jednak uzyskać dostępu do tych zmiennych w obrębie granicy await. Nie można uzyskać do nich dostępu przez granicę yield return.

To złagodzone ograniczenie umożliwia kompilatorowi bezpieczne i weryfikowalne korzystanie z ref zmiennych lokalnych i ref struct typów w większej liczbie miejsc. W tych metodach można bezpiecznie używać typów takich jak System.ReadOnlySpan<T>. Kompilator informuje, czy naruszasz reguły bezpieczeństwa.

W ten sam sposób język C# 13 umożliwia unsafe kontekstów w metodach iteratora. Jednak wszystkie instrukcje yield return i yield break muszą znajdować się w bezpiecznych kontekstach.

allows ref struct

Przed C# 13 nie można zadeklarować typów ref struct jako argumentu typu dla typu ogólnego lub metody. Teraz deklaracje typów ogólnych mogą dodawać anty-ograniczenie, allows ref struct. Te przesunięcie ograniczenia deklaruje, że argument typu podany dla tego parametru typu może być typem ref struct. Kompilator wymusza reguły bezpieczeństwa ref we wszystkich wystąpieniach tego typu parametru.

Można na przykład zadeklarować typ ogólny, taki jak następujący kod:

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

Dzięki temu typy, takie jak System.Span<T> i System.ReadOnlySpan<T>, mogą być używane z algorytmami ogólnymi, jeśli ma to zastosowanie. Aby dowiedzieć się więcej, zapoznaj się z aktualizacjami where oraz artykułem przewodnika programowania na temat ogólnych ograniczeń .

interfejsy ref struct

Przed 13. rokiem języka C# ref struct typy nie mogły implementować interfejsów. Począwszy od C# 13, mogą. Można zadeklarować, że typ ref struct implementuje interfejs. Jednak w celu zapewnienia reguł bezpieczeństwa ref nie można przekonwertować typu ref struct na typ interfejsu. Konwersja ta jest konwersją boksu i może naruszać bezpieczeństwo ref. Deklaracje jawne metod interfejsu w ref struct są dostępne wyłącznie przez parametr typu, gdzie ten parametr typu allows ref struct. Ponadto typy ref struct muszą implementować wszystkie metody zadeklarowane w interfejsie, w tym metody z domyślną implementacją.

Dowiedz się więcej na temat aktualizacji dotyczących typów ,ref struct i oraz dodania ogólnego ograniczenia allows ref struct.

Bardziej częściowi członkowie

Właściwości partial i indeksatory partial można zadeklarować w języku C# 13. Właściwości częściowe i indeksatory zazwyczaj stosują te same zasady co metody partial: należy utworzyć jedną deklarację i jedno wdrożenie deklaracji oraz jedno wdrożenie deklaracji. Podpisy dwóch deklaracji muszą być zgodne. Jednym z ograniczeń jest to, że nie można użyć deklaracji automatycznej właściwości dla implementującej właściwość częściową. Właściwości, które nie mają zdefiniowanej treści, są traktowane jako deklaracja.

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

Więcej można dowiedzieć się w artykule na temat członków częściowych.

Priorytet rozwiązywania przeciążenia

W C# 13 kompilator rozpoznaje OverloadResolutionPriorityAttribute, aby preferować jedno przeciążenie nad drugim. Autorzy bibliotek mogą użyć tego atrybutu, aby upewnić się, że nowe, lepsze przeciążenie jest preferowane w przypadku istniejącego przeciążenia. Możesz na przykład dodać nowe przeciążenie, które jest bardziej efektywne. Nie chcesz przerywać istniejącego kodu korzystającego z biblioteki, ale chcesz, aby użytkownicy zaktualizowali nową wersję podczas ponownego kompilowania. Aby poinformować kompilator, który powinien być preferowany, można użyć priorytetu rozwiązywania przeciążeń. Preferowane są te przeciążenia, które mają najwyższy priorytet.

Ta funkcja jest przeznaczona dla autorów bibliotek, aby uniknąć niejednoznaczności podczas dodawania nowych przeciążeń. Autorzy bibliotek powinni zachować ostrożność przy używaniu tego atrybutu, aby uniknąć nieporozumień.

Słowo kluczowe field

Słowo kluczowe kontekstowe field znajduje się w języku C# 13 jako funkcja w wersji zapoznawczej. Token field uzyskuje dostęp do syntetyzowanego przez kompilator pola zapasowego w akcesorze właściwości. Umożliwia pisanie treści metody dostępu bez deklarowania jawnego pola zapasowego w deklaracji typu. Można zadeklarować treść dla jednej lub obu metod dostępu dla właściwości wspieranej przez pole.

Funkcja field jest udostępniana jako funkcja w wersji zapoznawczej. Chcemy uczyć się z Twoich doświadczeń związanych z jego użytkowaniem. Istnieje potencjalna zmiana wprowadzająca niezgodność lub powodująca zamieszanie podczas czytania kodu w typach, które zawierają również pole o nazwie field. Możesz użyć @field lub this.field, aby rozróżnić słowo kluczowe field i identyfikator.

Ważny

Słowo kluczowe field to funkcja w wersji zapoznawczej w języku C# 13. Musisz używać platformy .NET 9 i ustawić element <LangVersion> na preview w pliku projektu, aby użyć kontekstowego słowa kluczowego field.

Należy zachować ostrożność przy użyciu funkcji słowa kluczowego field w klasie, która ma pole o nazwie field. Nowe słowo kluczowe field maskuje pole o nazwie field w zakresie akcesora właściwości. Możesz zmienić nazwę zmiennej field lub użyć tokenu @, aby odwołać się do identyfikatora field jako @field. Aby dowiedzieć się więcej, przeczytaj specyfikację funkcji dla słowa kluczowego field.

Jeśli wypróbujesz tę funkcję i masz opinię, dodaj ją do zgłoszenia funkcji w repozytorium csharplang.

Zobacz też