Паттерны списков
Паттерны списков (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;
}