Шрифт:
Интервал:
Закладка:
На заметку! Если вы имеете опыт объектно-ориентированного программирования, тогда можете считать структуры "легковесными типами классов", т.к. они предоставляют способ определения типа, который поддерживает инкапсуляцию, но не может использоваться для построения семейства взаимосвязанных типов. Когда возникает потребность в создании семейства типов, связанных отношением наследования, необходимо применять классы.
На первый взгляд процесс определения и использования структур выглядит простым, но, как часто бывает, самое сложное скрыто в деталях. Чтобы приступить к изучению основ типов структур, создайте новый проект по имени FunWithStructures. В языке C# структуры определяются с применением ключевого слова struct. Определите новую структуру по имени Point, представляющую точку, которая содержит две переменные типа int и набор методов для взаимодействия с ними:
struct Point
{
// Поля структуры.
public int X;
public int Y;
// Добавить 1 к позиции (X, Y).
public void Increment()
{
X++; Y++;
}
// Вычесть 1 из позиции (X, Y).
public void Decrement()
{
X--; Y--;
}
// Отобразить текущую позицию.
public void Display()
{
Console.WriteLine("X = {0}, Y = {1}", X, Y);
}
}
Здесь определены два целочисленных поля (X и Y) с использованием ключевого слова public, которое является модификатором управления доступом (их обсуждение будет продолжено в главе 5). Объявление данных с ключевым словом public обеспечивает вызывающему коду возможность прямого доступа к таким данным через переменную типа Point (посредством операции точки).
На заметку! Определение открытых данных внутри класса или структуры обычно считается плохим стилем программирования. Взамен рекомендуется определять закрытые данные, доступ и изменение которых производится с применением открытых свойств. Более подробные сведения приведены в главе 5.
Вот код, который позволяет протестировать тип Point:
Console.WriteLine("***** A First Look at Structures *****n");
// Создать начальную переменную типа Point.
Point myPoint;
myPoint.X = 349;
myPoint.Y = 76;
myPoint.Display();
// Скорректировать значения X и Y.
myPoint.Increment();
myPoint.Display();
Console.ReadLine();
Вывод выглядит вполне ожидаемо:
***** A First Look at Structures *****
X = 349, Y = 76
X = 350, Y = 77
Создание переменных типа структур
Для создания переменной типа структуры на выбор доступно несколько вариантов. В следующем коде просто создается переменная типа Point и затем каждому ее открытому полю данных присваиваются значения до того, как обращаться к членам переменной. Если не присвоить значения открытым полям данных (X и Y в данном случае) перед использованием структуры, то компилятор сообщит об ошибке:
// Ошибка! Полю Y не присвоено значение.
Point p1;
p1.X = 10;
p1.Display();
// Все в порядке! Перед использованием значения присвоены обоим полям.
Point p2;
p2.X = 10;
p2.Y = 10;
p2.Display();
В качестве альтернативы переменные типа структур можно создавать с применением ключевого слова new языка С#, что приводит к вызову стандартного конструктора структуры. По определению стандартный конструктор не принимает аргументов. Преимущество вызова стандартного конструктора структуры заключается в том, что каждое поле данных автоматически получает свое стандартное значение:
// Установить для всех полей стандартные значения,
// используя стандартный конструктор.
Point p1 = new Point();
// Выводит Х=0, Y=0
p1.Display();
Допускается также проектировать структуры со специальным конструктором, что позволяет указывать значения для полей данных при создании переменной, а не устанавливать их по отдельности. Конструкторы подробно рассматриваются в главе 5; однако в целях иллюстрации измените структуру Point следующим образом:
struct Point
{
// Поля структуры.
public int X;
public int Y;
// Специальный конструктор.
public Point(int xPos, int yPos)
{
X = xPos;
Y = yPos;
}
...
}
Затем переменные типа Point можно создавать так:
// Вызвать специальный конструктор.
Point p2 = new Point(50, 60);
// Выводит X=50,Y=60.
p2.Display();
Использование структур, допускающих только чтение (нововведение в версии 7.2)
Структуры можно также помечать как допускающие только чтение, если необходимо, чтобы они были неизменяемыми. Неизменяемые объекты должны устанавливаться при конструировании и поскольку изменять их нельзя, они могут быть более производительными. В случае объявления структуры как допускающей только чтение все свойства тоже должны быть доступны только для чтения. Но может возникнуть вопрос, как тогда устанавливать свойство, если оно допускает только чтение? Ответ заключается в том, что значения свойств должны устанавливаться во время конструирования структуры. Модифицируйте класс, представляющий точку, как показано ниже:
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
- QT 4: программирование GUI на С++ - Жасмин Бланшет - Программирование
- C# для профессионалов. Том II - Симон Робинсон - Программирование
- C# 4.0: полное руководство - Герберт Шилдт - Программирование
- Программирование игр и головоломок - Жак Арсак - Программирование
- Microsoft Visual C++ и MFC. Программирование для Windows 95 и Windows NT. Часть 2 - Александр Фролов - Программирование
- Графические интерфейсы пользователя Java - Тимур Сергеевич Машнин - Программирование
- Гибкое управление проектами и продуктами - Борис Вольфсон - Программирование
- Каждому проекту своя методология - Алистэр Коуберн - Программирование
- От «Энигмы» до ChatGPT - Рустам Агамалиев - Программирование / Экономика
- Как почистить сканы книг и сделать книгу - IvanStorogev? KpNemo - Программирование