В этой статье будут рассмотрены небольшие изменения, появившиеся в 8 версии языка C#:
- статические локальные функции;
- члены структур, не изменяющие их состояние;
- неуправляемые обобщенные структуры;
- присваивание при значении null;
- stackalloc во вложенных выражениях;
- улучшенная интерполяция строк.
|
Статические локальные функции
Локальные функции не являются чем-то новым для C#. Но именно начиная с 8 версии языка их можно объявлять статическими. На практике это означает что такая локальная функция:
- не захватывает контекст метода, в котором она объявлена (переменные и ссылку this на текущий экземпляр). Все необходимые значения должны быть переданы в нее через параметры.
- может использоваться внутри статических (static) методов класса.
Объявление статической локальной функции должно содержать ключевое слово static:
static [тип возвращаемого значения] [имя функции](аргументы) { тело функции }
Данный вариант функций отлично подходит для использования в конструкции switch , когда необходимо выполнить несколько операций.
Вот пример в котором хорошо видно отсутствие захвата переменных:
public string GetFormattedName(string firsName, string lastName)
{
// ...
var name = GetFullName(firsName, lastName);
// ...
return name;
static string GetFullName(string firsName, string lastName)
{
return $"{firsName} ${lastName}";
}
}
Члены структур, не изменяющие их состояния
Начиная с C# 7.2 появилась возможность объявлять неизменяемые структуры – readonly struct.
C# 8 развивает эту возможность, позволяя контролировать поведение отдельных членов структуры. В частности, обращения к члену структуры, объявленному c модификатором readonly, не должны изменять состояние самой структуры.
public struct IdStruct
{
public int Id { get; set; }
public readonly void DoSomethingImmutable()
{
this.Id++; // Ошибка компиляции при попытке изменить Id
}
}
Неуправляемые обобщенные (generic) структуры
Начиная с C# 8 обобщенные структуры могут быть неуправляемым типом, при условии если все ее члены также являются неуправляемыми типами. Например:
public struct Point<T>
{
public T X;
public T Y;
}
...
Span<Point<int>> points = stackalloc[]
{
new Point<int> { X = 0, Y = 0 }
};
Дополнительно можно использовать возможность C# 7.3 и ограничить T только неуправляемыми типами:
public struct Point
where T : unmanaged
{
public T X;
public T Y;
}
Присваивание при значении null
В C# 8 добавлен новый оператор ??=. Он присвоит значение в левую часть только если значение левой части выражения равно null .
a ??= b;
По сути это короткий аналог записи:
if (a == null)
a = b;
Использование stackalloc во вложенных выражениях
Поскольку stackalloc возвращает Span<T> и ReadOnlySpan<T>, то C# 8 позволяет использовать его во вложенных выражениях, если в них допустымы указанные типы:
Span<int> numbers = stackalloc[] { 1, 2, 3, 4, 5, 6 };
var index = numbers.IndexOfAny(stackalloc[] { 2, 4, 6, 8 });
Улучшенный синтаксис для интерполяции строк.
В C# 8 следующие типы записи строк трактуются одинаково:
var str1 = $@"...";
var str2 = @$"...";