Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
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 2026 lub zestawu .NET 10 SDK:
- Członkowie rozszerzenia
- Przypisanie warunkowe o wartości null
-
nameofobsługuje niezwiązane typy ogólne -
Więcej niejawnych konwersji dla
Span<T>iReadOnlySpan<T> - Modyfikatory dla prostych parametrów lambda
-
fieldwłaściwości kopii zapasowej -
partialzdarzenia i konstruktory - zdefiniowane przez użytkownika operatory przypisania złożonego
- nowe dyrektywy preprocesora dla aplikacji opartych na plikach
C# 14 to najnowsza wersja języka C#. 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 2026, który zawiera zestaw .NET 10 SDK.
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. Rozszerzenia te mogą obejmować operatory zdefiniowane przez użytkownika zaimplementowane jako metody rozszerzenia statycznego. 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 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>();
// static user defined operator:
public static IEnumerable<TSource> operator + (IEnumerable<TSource> left, IEnumerable<TSource> right) => left.Concat(right);
}
}
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.
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, outlub 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.