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:
-
params
kolekcje -
nowy typ
lock
i semantyka. -
Nowa sekwencja ucieczki —
\e
. - Ulepszenia naturalnego typu dla grupy metod
- niejawny dostęp do indeksatora w inicjatorach obiektów
-
Włącz lokalne
ref
i kontekstyunsafe
w iteratorach i metodach asynchronicznych -
Włącz typy
ref struct
w celu zaimplementowania interfejsów. - Zezwalaj na typy struktur ref jako argumenty parametrów typu w typach ogólnych.
-
Właściwości częściowe i indeksatory są teraz dozwolone w typach
partial
. - priorytet rozpoznawania przeciążenia umożliwia autorom bibliotek wyznaczenie jednego przeciążenia jako lepszego niż inne.
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
.