Co nowego w języku C# 10

Język C# 10 dodaje następujące funkcje i ulepszenia języka C#:

Język C# 10 jest obsługiwany na platformie .NET 6. Aby uzyskać więcej informacji, zobacz Przechowywanie wersji języka C#.

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

Uwaga

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

Struktury rekordów

Rekordy typu wartości można zadeklarować przy użyciu record struct deklaracji lub readonly record struct . Teraz można wyjaśnić, że element record jest typem odwołania z deklaracją record class .

Ulepszenia typów struktur

Język C# 10 wprowadza następujące ulepszenia związane z typami struktury:

  • Konstruktor bez parametrów wystąpienia można zadeklarować w typie struktury i zainicjować pole wystąpienia lub właściwość w jego deklaracji. Aby uzyskać więcej informacji, zobacz sekcję Inicjowanie struktury i wartości domyślne w artykule Typy struktury.
  • Lewy operand with wyrażenia może mieć dowolny typ struktury lub anonimowy (odwołanie).

Procedura obsługi ciągów interpolowanych

Możesz utworzyć typ, który tworzy wynikowy ciąg z wyrażenia ciągu interpolowanego. Biblioteki platformy .NET używają tej funkcji w wielu interfejsach API. Możesz go skompilować, wykonując czynności opisane w tym samouczku.

Globalne dyrektywy using

Modyfikator można dodać global do dowolnej dyrektywy using, aby poinstruować kompilator, że dyrektywa ma zastosowanie do wszystkich plików źródłowych w kompilacji. Zazwyczaj są to wszystkie pliki źródłowe w projekcie.

Deklaracja przestrzeni nazw o zakresie plików

Możesz użyć nowej formy deklaracjinamespace, aby zadeklarować, że wszystkie następujące deklaracje są elementami członkowskimi zadeklarowanej przestrzeni nazw:

namespace MyNamespace;

Ta nowa składnia pozwala zaoszczędzić miejsce zarówno w poziomie, jak i w pionie dla namespace deklaracji.

Rozszerzone wzorce właściwości

Począwszy od języka C# 10, można odwoływać się do zagnieżdżonych właściwości lub pól we wzorcu właściwości. Na przykład wzorzec formularza

{ Prop1.Prop2: pattern }

jest prawidłowy w języku C# 10 lub nowszym i równoważnym

{ Prop1: { Prop2: pattern } }

prawidłowe w języku C# 8.0 lub nowszym.

Aby uzyskać więcej informacji, zobacz notatkę dotyczącą propozycji funkcji rozszerzonych wzorców właściwości. Aby uzyskać więcej informacji na temat wzorca właściwości, zobacz sekcję Wzorzec właściwości artykułu Patterns (Wzorce).

Ulepszenia wyrażeń lambda

Język C# 10 zawiera wiele ulepszeń sposobu obsługi wyrażeń lambda:

  • Wyrażenia lambda mogą mieć typ naturalny, w którym kompilator może wywnioskować typ delegata z wyrażenia lambda lub grupy metod.
  • Wyrażenia lambda mogą zadeklarować typ zwracany, gdy kompilator nie może go wywnioskować.
  • Atrybuty można stosować do wyrażeń lambda.

Te funkcje sprawiają, że wyrażenia lambda są bardziej podobne do metod i funkcji lokalnych. Ułatwiają one używanie wyrażeń lambda bez deklarowania zmiennej typu delegata i bezproblemowo współpracują z nowymi interfejsami API ASP.NET Core Minimal.

Stałe ciągi interpolowane

W języku C# 10 ciągi mogą być inicjowane przy użyciu interpolacji ciągów, const jeśli wszystkie symbole zastępcze są ciągami stałymi. Interpolacja ciągów może tworzyć bardziej czytelne ciągi stałe podczas tworzenia ciągów stałych używanych w aplikacji. Wyrażenia zastępcze nie mogą być stałymi liczbowymi, ponieważ te stałe są konwertowane na ciągi w czasie wykonywania. Bieżąca kultura może mieć wpływ na ich reprezentację ciągu. Dowiedz się więcej w dokumentacji językowej w const wyrażeniach.

Typy rekordów mogą zapieczętować ciągi

W języku C# 10 można dodać sealed modyfikator podczas zastępowania ToString w typie rekordu. ToString Uszczelnianie metody uniemożliwia kompilatorowi synchronizowanie ToString metody dla wszelkich typów rekordów pochodnych. A sealedToString zapewnia, że wszystkie typy rekordów pochodnych używają ToString metody zdefiniowanej w typowym typie rekordu podstawowego. Więcej informacji na temat tej funkcji można znaleźć w artykule dotyczącym rekordów.

Przypisanie i deklaracja w tej samej dekonstrukcji

Ta zmiana powoduje usunięcie ograniczenia z wcześniejszych wersji języka C#. Wcześniej dekonstrukcja może przypisać wszystkie wartości do istniejących zmiennych lub zainicjować nowo zadeklarowane zmienne:

// Initialization:
(int x, int y) = point;

// assignment:
int x1 = 0;
int y1 = 0;
(x1, y1) = point;

C# 10 usuwa to ograniczenie:

int x = 0;
(x, int y) = point;

Ulepszone określone przypisanie

Przed C# 10 było wiele scenariuszy, w których określone przypisanie i analiza stanu null wygenerowały ostrzeżenia, które były fałszywie dodatnie. Zazwyczaj dotyczy to porównań do stałych logicznych, uzyskiwania dostępu do zmiennej tylko w true instrukcjach or false i if wyrażeń łączenia wartości null. Te przykłady wygenerowały ostrzeżenia w poprzednich wersjach języka C#, ale nie w języku C# 10:

string representation = "N/A";
if ((c != null && c.GetDependentValue(out object obj)) == true)
{
   representation = obj.ToString(); // undesired error
}

// Or, using ?.
if (c?.GetDependentValue(out object obj) == true)
{
   representation = obj.ToString(); // undesired error
}

// Or, using ??
if (c?.GetDependentValue(out object obj) ?? false)
{
   representation = obj.ToString(); // undesired error
}

Głównym wpływem tej poprawy jest to, że ostrzeżenia dotyczące określonego przypisania i analizy stanu null są dokładniejsze.

Zezwalaj na atrybut AsyncMethodBuilder w metodach

W języku C# 10 i nowszych można określić innego konstruktora metody asynchronicznej dla jednej metody, oprócz określenia typu konstruktora metody dla wszystkich metod, które zwracają dany typ przypominający zadanie. Niestandardowy konstruktor metod asynchronicznych umożliwia zaawansowane scenariusze dostrajania wydajności, w których dana metoda może korzystać z konstruktora niestandardowego.

Aby dowiedzieć się więcej, zobacz sekcję w AsyncMethodBuilder artykule na temat atrybutów odczytanych przez kompilator.

Diagnostyka atrybutów CallerArgumentExpression

Można użyć System.Runtime.CompilerServices.CallerArgumentExpressionAttribute polecenia , aby określić parametr, który kompilator zastępuje tekstową reprezentacją innego argumentu. Ta funkcja umożliwia bibliotekom tworzenie bardziej szczegółowej diagnostyki. Poniższy kod testuje warunek. Jeśli warunek ma wartość false, komunikat o wyjątku zawiera tekstowy reprezentacja argumentu przekazanego do conditionelementu :

public static void Validate(bool condition, [CallerArgumentExpression("condition")] string? message=null)
{
    if (!condition)
    {
        throw new InvalidOperationException($"Argument failed validation: <{message}>");
    }
}

Więcej informacji na temat tej funkcji można znaleźć w artykule dotyczącym atrybutów informacji o obiekcie wywołującym w sekcji dokumentacji językowej.

Ulepszona #line pragma

Język C# 10 obsługuje nowy format dla #line pragma. Prawdopodobnie nie użyjesz nowego formatu, ale zobaczysz jego efekty. Ulepszenia umożliwiają bardziej szczegółowe dane wyjściowe w językach specyficznych dla domeny(DSL), takich jak Razor. Aparat Razor używa tych ulepszeń, aby poprawić środowisko debugowania. Znajdziesz debugery, które mogą dokładniej wyróżnić źródło Razor. Aby dowiedzieć się więcej na temat nowej składni, zobacz artykuł dotyczący dyrektyw preprocesora w dokumentacji językowej. Możesz również przeczytać specyfikację funkcji dla przykładów opartych na razor.