Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Język C# 14 zawiera następujące nowe funkcje. Możesz wypróbować te funkcje przy użyciu najnowszej wersji programu Visual Studio 2022 lub zestawu .NET 10 SDK:
- Członkowie rozszerzenia
- Przypisanie warunkowe o wartości null
-
nameof
obsługuje niezwiązane typy ogólne -
Więcej niejawnych konwersji dla
Span<T>
iReadOnlySpan<T>
- Modyfikatory dla prostych parametrów lambda
-
field
właściwości kopii zapasowej -
partial
zdarzenia i konstruktory - zdefiniowane przez użytkownika operatory przypisania złożonego
Język C# 14 jest obsługiwany na platformie .NET 10. Aby uzyskać więcej informacji, zobacz wersjonowanie języka C#.
Najnowszy zestaw .NET 10 SDK można pobrać ze strony pobierania platformy .NET. Możesz również pobrać program Visual Studio 2022, który zawiera zestaw .NET 10 SDK.
Nowe funkcje są dodawane do strony "Co nowego w języku C#", gdy są one dostępne w publicznej wersji zapoznawczej. Sekcja zestawu roboczego na stronie stanu funkcji roslyn śledzi, kiedy nadchodzące funkcje są scalane z gałęzią główną. Ten artykuł został ostatnio zaktualizowany dla platformy .NET 10 (wersja zapoznawcza 1).
Wszystkie zmiany powodujące niezgodność wprowadzone w języku C# 14 można znaleźć w naszym artykule dotyczącym zmian powodujących niezgodność.
Uwaga
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.
Elementy członkowskie rozszerzenia
Język C# 14 dodaje nową składnię do definiowania składowych rozszerzeń. Nowa składnia umożliwia deklarowanie właściwości rozszerzenia oprócz metod rozszerzeń. Można również zadeklarować członków rozszerzeń, które rozszerzają typ, a nie jego instancję. Innymi słowy, ci nowi członkowie rozszerzenia mogą być widoczni jako statyczni członkowie typu, który rozszerzasz. Poniższy przykład kodu przedstawia przykład różnych rodzajów elementów członkowskich rozszerzenia, które można zadeklarować:
public static class Enumerable
{
// Extension block
extension<TSource>(IEnumerable<TSource> source) // extension members for IEnumerable<TSource>
{
// Extension property:
public bool IsEmpty => !source.Any();
// Extension indexer:
public TSource this[int index] => source.Skip(index).First();
// Extension method:
public IEnumerable<TSource> Where(Func<TSource, bool> predicate) { ... }
}
// extension block, with a receiver type only
extension<TSource>(IEnumerable<TSource>) // static extension members for IEnumerable<Source>
{
// static extension method:
public static IEnumerable<TSource> Combine(IEnumerable<TSource> first, IEnumerable<TSource> second) { ... }
// static extension property:
public static IEnumerable<TSource> Identity => Enumerable.Empty<TSource>();
}
}
Członkowie w pierwszym bloku rozszerzenia są wywoływani tak, jakby byli członkami wystąpienia elementu IEnumerable<TSource>
, na przykład sequence.IsEmpty
. Członkowie w drugim bloku rozszerzenia są wywoływani, tak jakby byli statycznymi członkami IEnumerable<TSource>
, na przykład IEnumerable<int>.Identity
.
Aby dowiedzieć się więcej szczegółów, przeczytaj artykuł w przewodniku programowania na temat elementów członkowskich rozszerzenia, artykuł referencyjny języka dotyczący extension
słowa kluczowego, oraz specyfikację nowej funkcji rozszerzeń elementów członkowskich.
Słowo kluczowe field
Token field
umożliwia napisanie treści metody dostępu właściwości bez deklarowania jawnego pola zapasowego. Token field
jest zastępowany syntetyzowanym polem kopii zapasowej kompilatora.
Na przykład, wcześniej, jeśli chciałeś upewnić się, że właściwości string
nie można ustawić na null
, trzeba było zadeklarować pole pomocnicze i zaimplementować obie metody dostępu:
private string _msg;
public string Message
{
get => _msg;
set => _msg = value ?? throw new ArgumentNullException(nameof(value));
}
Teraz możesz uprościć kod w celu:
public string Message
{
get;
set => field = value ?? throw new ArgumentNullException(nameof(value));
}
Można zadeklarować treść dla jednej lub obu metod dostępu dla właściwości wspieranej przez pole.
Istnieje potencjalna zmiana powodująca niezgodność lub błąd podczas odczytywania kodu w typach, które zawierają również symbol o nazwie field
. Możesz użyć @field
lub this.field
w celu rozróżnienia między słowem kluczowym field
a identyfikatorem, lub możesz zmienić nazwę bieżącego symbolu field
, aby zapewnić lepsze rozróżnienie.
Jeśli wypróbujesz tę funkcję i otrzymasz opinię, skomentuj problem z funkcjącsharplang
w repozytorium.
Słowo kluczowe kontekstowe field
znajduje się w języku C# 13 jako funkcja w wersji zapoznawczej.
Niejawne konwersje zakresu
Język C# 14 wprowadza pierwszorzędne wsparcie dla System.Span<T> i System.ReadOnlySpan<T>. Ta obsługa obejmuje nowe niejawne konwersje umożliwiające bardziej naturalne programowanie przy użyciu tych typów.
Span<T>
i ReadOnlySpan<T>
są używane na wiele kluczowych sposobów w języku C# i środowisku uruchomieniowym. Ich wprowadzenie poprawia wydajność bez ryzyka bezpieczeństwa. Język C# 14 rozpoznaje relację i obsługuje niektóre konwersje między ReadOnlySpan<T>
, Span<T>
i T[]
. Typy span mogą być odbiornikami metod rozszerzeń, łączyć się z innymi konwersjami i pomagać w scenariuszach wnioskowania typów ogólnych.
Listę niejawnych konwersji zakresu można znaleźć w artykule dotyczącym wbudowanych typów w sekcji odniesienia językowego. Aby dowiedzieć się więcej, przeczytaj specyfikację funkcji dla typów zakresu pierwszej klasy.
Typy generyczne niezwiązane i nameof
Począwszy od języka C# 14, argumentem nameof
może być niezwiązany typ ogólny. Na przykład nameof(List<>)
funkcja oblicza wartość List
. We wcześniejszych wersjach języka C# można było użyć tylko zamkniętych typów ogólnych, takich jak List<int>
, w celu zwrócenia nazwy List
.
Proste parametry lambda z modyfikatorami
Można dodać modyfikatory parametrów, takie jak scoped
, ref
, in
, out
lub ref readonly
do parametrów wyrażenia lambda bez określania typu parametru:
delegate bool TryParse<T>(string text, out T result);
// ...
TryParse<int> parse1 = (text, out result) => Int32.TryParse(text, out result);
Wcześniej dodanie wszelkich modyfikatorów było dozwolone tylko wtedy, gdy deklaracje parametrów zawierały typy parametrów. Poprzednia deklaracja wymagałaby typów dla wszystkich parametrów:
TryParse<int> parse2 = (string text, out int result) => Int32.TryParse(text, out result);
Modyfikator params
nadal wymaga jawnie wpisanej listy parametrów.
Więcej informacji na temat tych zmian można uzyskać w artykule dotyczącym wyrażeń lambda w dokumentacji języka C#.
Bardziej częściowi członkowie
Teraz można zadeklarować konstruktory wystąpień i zdarzenia jako częściowe członki.
Konstruktory częściowe i zdarzenia częściowe muszą zawierać dokładnie jedną deklarację definiującą i jedną deklarację implementowania.
Tylko deklaracja implementowania konstruktora częściowego może zawierać inicjator konstruktora: this()
lub base()
. Tylko jedna deklaracja typu częściowego może zawierać podstawową składnię konstruktora.
Deklaracja implementacji zdarzenia częściowego musi zawierać add
i remove
akcesory. Deklaracja definiująca deklaruje zdarzenie podobne do pola.
Przypisanie złożone zdefiniowane przez użytkownika
Więcej informacji można znaleźć w specyfikacji funkcji przypisywania złożonego definiowanego przez użytkownika.
Przypisanie warunkowe o wartości null
Operatory dostępu członków zależne od null, ?.
i ?[]
, mogą być teraz używane po lewej stronie przypisania lub złożonego przypisania.
Przed wersją C# 14, należało sprawdzić, czy zmienna ma wartość null, zanim przypisano ją do właściwości.
if (customer is not null)
{
customer.Order = GetCurrentOrder();
}
Powyższy kod można uprościć przy użyciu ?.
operatora :
customer?.Order = GetCurrentOrder();
Prawa strona =
operatora jest oceniana tylko wtedy, gdy lewa strona nie ma wartości null. Jeśli customer
jest null, kod nie wywołuje GetCurrentOrder
.
Oprócz przypisania można używać operatorów dostępu warunkowego o wartości null z operatorami przypisania złożonego (+=
, -=
, i innych). Jednak przyrost i dekrementacja ++
i --
, nie są dozwolone.
Więcej informacji można znaleźć w artykule dotyczącym dostępu warunkowego do składowych oraz specyfikacji funkcji przypisania warunkowego o wartości null.