Нововведения в C# 11

Последнее обновление: 02.11.2022

Паттерны списков

Паттерны списков (list pattern) позволяют сопоставлять выражения со списками и массивами. Можно сопоставлять для списка-паттерна можно установить все элементы массивы:

[2, 3, 4, 5] // этот паттерн соответствует любому массиву/списку, 
            // который равен [2, 3, 4, 5]

Также с помощью символа подчеркивания _ можно задать произвольный элемент, значение которого не имеет значения:

[_, 5] // этот паттерн соответствует любому массиву/списку из двух элементов
        // где второй элемент равен 5 (например, [1, 5] или [25, 5])

И, кроме того, с помощью slice-паттерна .. можно задать произвольное количество элементов:

[2, .., 5] // этот паттерн соответствует любому массиву/списку, где первый элемент равен 2
        // а последний элемент равен 5, а между 2 и 5 может быть произвольное количество произвольных элементов
        // (например, [2, 5] или [2, 3, 9, 5])

Пример применения:

Console.WriteLine(GetNumber(new[] { 2, 3, 5 }));        // 1
Console.WriteLine(GetNumber(new[] { 2, 4, 5 }));        // 2
Console.WriteLine(GetNumber(new[] { 2, 3, 4, 5 }));     // 3
Console.WriteLine(GetNumber(new[] { 1, 2, 3 }));        // 4
Console.WriteLine(GetNumber(new int[] { }));            // 4

int GetNumber(int[] values) => values switch
{
    [2, 3, 5] => 1,
    [2, _, 5] => 2,
    [2, .., 5] => 3,
    [..] => 4
};

Обобщения в атрибутах

В C# 11 можно определять обобщенные классы атрибутов:

class C
{
    [Reader<int>]
    public void M() 
    {
    }
}

class ReaderAttribute<T> : Attribute
{
}

Многострочные строки

С помощью трех пар двойных кавычек можно оформить многострочный текст, в том числе с применением интерполяции:

Print();
PrintValue("hello");

void Print()
{
    string text = """
              <element attr="content">
                <body>
                </body>
              </element>
              """;
    Console.WriteLine(text);
}

void PrintValue(string val)
{
    string text = $"""
              <element attr="content">
                <body>
                {val}
                </body>
              </element>
              """;
    Console.WriteLine(text);
}

Строковые литералы UTF-8

C# 11 позволяет автоматически сконвертировать строки с символами UTF-8 в их бинарное представление в виде объекта ReadOnlySpan<byte>.

ReadOnlySpan<byte> span2 = "hello"u8; 

Чтобы указать, что строка представляет utf-8, к строке добавляется суффикс u8

Файл как область видимости

C# 11 добавил еще один модификатор видимости - file, который с применяется к классам, структурам, делегатам, перечислениям, интерфейсам. Типы с этим модификаторо могут использоваться только внутри текущего файла кода.

file class Person
{
}

Данный модификатор не может использоваться в паре с другими модификаторами.

модификатор required

Модификатор required (добавлен в C# 11) указывает, что поле или свойства с этим модификатором обязательно должны быть инициализированы. Например, в следующем примере мы получим ошибку:

Person tom = new Person();  // ошибка - свойства Name и Age не инициализированы
public class Person
{
    public required string Name { get; set; }
    public required int Age { get; set; }
}

Здесь свойства Name и Age отмечены как обязательные для инициализации с помощью модификатора required, поэтому необходимо использовать инициализатор для их инициализации:

Person tom = new Person { Name = "Tom", Age = 38 }; // ошибки нет

Причем не важно, устанавливаем эти свойства в конструкторе или инициализируем при определении, все равно надо использовать инициализатор для установки их значений. Например, в следующем примере мы получим ошибку:

Person bob = new Person("Bob"); // ошибка - свойства Name и Age все равно надо установить в инициализаторе

public class Person
{
    public Person(string name)
    {
        Name = name;
    }
    public required string Name { get; set; }
    public required int Age { get; set; } = 22;
}
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850