Язык программирования C#9 и платформа .NET5
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. Вместо определения их в виде полей они создаются как автоматические свойства, доступные только для чтения. Автоматические свойства рассматриваются в главе 5.YИспользование членов, допускающих только чтение (нововведение в версии 8.0)
В версии C# 8.0 появилась возможность объявления индивидуальных полей структуры как
. Это обеспечивает более высокий уровень детализации, чем объявление целой структуры как допускающей только чтение. Модификаторreadonlyможет применяться к методам, свойствам и средствам доступа для свойств. Добавьте следующий код структуры в свой файл за пределами классаreadonly:Programstruct 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Ниже перечислены дополнительные ограничения структур
:ref• их нельзя присваивать переменной типа
илиobject, и они не могут быть интерфейсного типа;dynamic• они не могут реализовывать интерфейсы;
• они не могут использоваться в качестве свойства структуры, не являющейся
;ref• они не могут применяться в асинхронных методах, итераторах, лямбда-выражениях или локальных функциях.
Показанный далее код, в котором создается простая структура и затем предпринимается попытка создать в этой структуре свойство, типизированное как структура
, не скомпилируется;refstruct NormalPoint{// Этот код не скомпилируется.public PointWithRef PropPointer { get; set; }}Модификаторы
иreadonlyможно сочетать для получения преимуществ и ограничений их обоих.refИспользование освобождаемых структур ref (нововведение в версии 8.0)
Как было указано в предыдущем разделе, структуры
(и структурыref, допускающие только чтение) не могут реализовывать интерфейсы, а потому реализоватьrefнельзя. В версии C# 8.0 появилась возможность делать структурыIDisposableи структуры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(){// Выполнить здесь очистку любых ресурсов.