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
из кучи невозможны. Отличие между стеком и кучей объясняется в следующем разделе.
Ниже перечислены дополнительные ограничения структур
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()
{
// Выполнить здесь очистку любых ресурсов.