Как вы уже знаете, классы — это ссылочные типы. Это означает, что к объектам классов доступ осуществляется через ссылку. Этим они отличаются от типов значений, к которым в С# реализован прямой доступ. Но иногда желательно получать прямой доступ и к объектам, как в случае нессылочных типов. Одна из причин для этого — эффективность. Ведь очевидно, что доступ к объектам классов через ссылки увеличивает расходы системных ресурсов, в том числе и памяти. Даже для очень маленьких объектов требуются существенные объемы памяти. Для компенсации упомянутых расходов времени и пространства в С# предусмотрены структуры. Структура подобна классу, но она относится к типу значений, а не к ссылочным типам. Структуры объявляются с использованием ключевого слова struct и синтаксически подобны классам. Формат записи структуры таков:
struct имя : интерфейсы { // объявления членов
Элемент имя означает имя структуры.
Структуры не могут наследовать другие структуры или классы. Структуры не могут использоваться в качестве базовых для других структур или классов. (Однако, подобно другим С#-типам, структуры наследуют класс object). Структура может реализовать один или несколько интерфейсов. Они указываются после имени структуры и отделяются запятыми. Как и у классов, членами структур могут быть методы, поля, индексаторы, свойства, операторные методы и события. Структуры могут также определять конструкторы, но не деструкторы. Однако для структуры нельзя определить конструктор по умолчанию (без параметров). Дело в том, что конструктор по умолчанию автоматически определяется для всех структур, и его изменить нельзя. Поскольку структуры не поддерживают наследования, члены структуры нельзя определять с использованием модификаторов abstract, virtual или protected.
Объект структуры можно создать с помощью оператора new, подобно любому объекту класса, но это не обязательно. Если использовать оператор new, вызывается указанный конструктор, а если не использовать его, объект все равно будет создан, но не инициализирован. В этом случае вам придется выполнить инициализацию вручную, рассмотрим пример использования структуры для хранения информации о книге.
// Демонстрация использования структуры.
using System;
// Определениеструктуры,
struct Book {
public string author;
public string title;
public int copyright;
public Book(string a, string t, int c) {
author = a;
title = t;
copyright = c;
// Демонстрируем использование структуры Book,
classStructDemo {
public static void Main() {
Book bookl = new Book("Herb Schildt",
"C# A Beginner's Guide", 2001); // Вызов явнозаданногоконструктора.
Book book2 = new Book(); // Вызов конструктора по умолчанию.
Book ЬоокЗ; // Создание объекта без вызова конструктора.
// Console.WriteLine(ЬоокЗ.title); // Ошибка: сначала необходима инициализация.
ЬоокЗ.title = "Red Storm Rising";
Console.WriteLine(ЬоокЗ.title); // Теперьвсе Ok!
Вот результаты выполнения этой программы:
С# A Beginner's Guide, автор Herb Schildt, (с) 2001
Член book2.title содержит null.
Теперь структура book2 содержит:
Brave New World, автор Aldous Huxley, (с) 1932
Red Storm Rising
Как видно из результатов выполнения этой программы, структура может быть создана либо с помощью оператора new, который вызывает соответствующий конструктор, либо простым объявлением объекта. При использовании оператора new поля структуры будут инициализированы, причем это сделает либо конструктор по умолчанию (он инициализирует все поля значениями по умолчанию), либо конструктор, определенный пользователем. Если оператор new не используется, как в случае объекта bоокЗ, созданный таким образом объект остается неинициализированным, и его поля должны быть установлены до начала использования.
При присваивании одной структуры другой создается копия этого объекта. Это — очень важное отличие struct-объекта от с lass-объекта. Как упоминалось выше, присваивая одной ссылке на класс другую, вы просто меняете объект, на который ссылается переменная, стоящая с левой стороны от оператора присваивания. А присваивая одной struct-переменной другую, вы создаете копию объекта, указанного с правой стороны от оператора присваивания. Рассмотрим, например, следующую программу: