Действие ключевого слова this
В конструкторе экземпляра или члене-функции экземпляра класса ключевое слово this классифицируется как значение. Таким образом, хотя ключевое слово this можно использовать для ссылки на экземпляр, для которого была вызвана данная функция-член, присваивание для this в функции-члене класса недоступно.
В конструкторе экземпляра структуры ключевое слово this соответствует параметру out типа структуры, а в функции-члене экземпляра структуры ключевое слово this соответствует параметру ref типа структуры. В обоих случаях this считается переменной, что позволяет изменить всю структуру, для которой была вызвана эта функция-член, путем присваивания в this или передачи this в качестве параметра ref или out.
Инициализаторы полей
Как рассматривалось в §11.3.4, значение структуры по умолчанию состоит из значения, полученного путем установки для всех полей с типом значения соответствующих значений по умолчанию, а для всех полей ссылочного типа — значения null. По этой причине в структуре объявления полей экземпляра не могут содержаться инициализаторы переменных. Это ограничение действует только в отношении полей экземпляра. Статические поля структуры могут содержать инициализаторы переменных.
Пример:
struct Point
{
public int x = 1; // Error, initializer not permitted
public int y = 1; // Error, initializer not permitted
}
является неправильным, так как объявления полей экземпляра содержат инициализаторы переменных.
Конструкторы
Для структуры, в отличие от класса, не допускается объявление конструктора экземпляра без параметров. Вместо этого каждая структура неявно содержит конструктор экземпляра без параметров, который всегда возвращает значение, полученное путем установки для всех полей с типом значения соответствующих значений по умолчанию, а для всех полей с ссылочным типом — значения NULL (§4.1.2). В структуре можно объявлять конструкторы экземпляров с параметрами. Пример
struct Point
{
int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
В приведенном выше объявлении операторы
Point p1 = new Point();
Point p2 = new Point(0, 0);
создают объекты Point, свойства которых x и y инициализированы нулевыми значениями.
Конструктор экземпляра структуры не может содержать инициализатор конструктора в форме base(...).
Если в конструкторе экземпляра структуры не указан инициализатор конструктора, переменная this соответствует параметру out типа структуры, при этом, аналогично параметру out, объект this должен быть определенно присвоен (§5.3) в каждой точке возвращения из конструктора. Если в конструкторе экземпляра структуры указан инициализатор конструктора, переменная this соответствует параметру ref с типом структуры и, аналогично параметру ref, переменная this считается определенно присвоенной в точке входа в тело конструктора. Рассмотрим приведенную ниже реализацию конструктора:
struct Point
{
int x, y;
public int X {
set { x = value; }
}
public int Y {
set { y = value; }
}
public Point(int x, int y) {
X = x; // error, this is not yet definitely assigned
Y = y; // error, this is not yet definitely assigned
}
}
Ни одна из функций-членов экземпляра (включая методы доступа set для свойств X и Y) не может быть вызвана до тех пор, пока все поля создаваемой структуры не будут определенно присвоены. Однако, если бы объект Point был классом, а не структурой, реализация конструктора экземпляра была бы разрешена.
Деструкторы
В структуре не разрешается объявлять деструктор.
Статические конструкторы
Для статических конструкторов структур в основном действуют те же правила, что и для статических конструкторов классов. Выполнение статического конструктора структуры запускается первым из следующих событий в домене приложения:
· Ссылка на статический член с типом структуры.
· Вызов явным образом объявленного конструктора с типом структуры.
Создание значений по умолчанию (§11.3.4) с типом структуры не ведет к вызову статического конструктора. В качестве примера можно указать начальные значения элементов массива.
Примеры структур
Ниже приводится два примера использования типов struct для создания типов, которые могут использоваться аналогично предопределенным типам языка, но имеют измененную семантику.