readonly struct ReadOnlyPoint
{
// Fields of the structure.
public int X {get; }
public int Y { get; }
// Display the current position and name.
public void Display()
{
Console.WriteLine($"X = {X}, Y = {Y}");
}
public ReadOnlyPoint(int xPos, int yPos)
{
X = xPos;
Y = yPos;
}
}
Методы Increment() и Decrement() были удалены, т.к. переменные допускают только чтение. Обратите внимание на свойства X и Y. Вместо определения их в виде полей они создаются как автоматические свойства, доступные только для чтения. Автоматические свойства рассматриваются в главе 5.
Использование членов, допускающих только чтение (нововведение в версии 8.0)
В версии C# 8.0 появилась возможность объявления индивидуальных полей структуры как readonly. Это обеспечивает более высокий уровень детализации, чем объявление целой структуры как допускающей только чтение. Модификатор readonly может применяться к методам, свойствам и средствам доступа для свойств. Добавьте следующий код структуры в свой файл за пределами класса Program:
struct PointWithReadOnly
{
// Поля структуры.
public int X;
public readonly int Y;
public readonly string Name;
// Отобразить текущую позицию и название.
public readonly void Display()
{
Console.WriteLine($"X = {X}, Y = {Y}, Name = {Name}");
}
// Специальный конструктор.
public PointWithReadOnly(int xPos, int yPos, string name)
{
X = xPos;
Y = yPos;
Name = name;
}
}
Для использования этой новой структуры добавьте к операторам верхнего уровня такой код:
PointWithReadOnly p3 =
new PointWithReadOnly(50,60,"Point w/RO");
p3.Display();
Использование структур ref (нововведение в версии 7.2)
При определении структуры в C# 7.2 также появилась возможность применения модификатора ref. Он требует, чтобы все экземпляры структуры находились в стеке и не могли присваиваться свойству другого класса. Формальная причина для этого заключается в том, что ссылки на структуры ref из кучи невозможны. Отличие между стеком и кучей объясняется в следующем разделе.
(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})
Ниже перечислены дополнительные ограничения структур ref:
• их нельзя присваивать переменной типа object или dynamic, и они не могут быть интерфейсного типа;
• они не могут реализовывать интерфейсы;
• они не могут использоваться в качестве свойства структуры, не являющейся ref;
• они не могут применяться в асинхронных методах, итераторах, лямбда-выражениях или локальных функциях.
Показанный далее код, в котором создается простая структура и затем предпринимается попытка создать в этой структуре свойство, типизированное как структура ref, не скомпилируется;
struct NormalPoint
{
// Этот код не скомпилируется.
public PointWithRef PropPointer { get; set; }
}
Модификаторы readonly и ref можно сочетать для получения преимуществ и ограничений их обоих.
Использование освобождаемых структур ref (нововведение в версии 8.0)
Как было указано в предыдущем разделе, структуры ref (и структуры ref, допускающие только чтение) не могут реализовывать интерфейсы, а потому реализовать IDisposable нельзя. В версии C# 8.0 появилась возможность делать структуры ref и структуры ref, допускающие только чтение, освобождаемыми, добавляя открытый метод void Dispose().
Добавьте в главный файл следующее определение структуры:
ref struct DisposableRefStruct
{
public int X;
public readonly int Y;
public readonly void Display()
{
Console.WriteLine($"X = {X}, Y = {Y}");
}
// Специальный конструктор.
public DisposableRefStruct(int xPos, int yPos)
{
X = xPos;
Y = yPos;
Console.WriteLine("Created!"); // Экземпляр создан!
}
public void Dispose()
{
// Выполнить здесь очистку любых ресурсов.