Страницы

Поиск по вопросам

четверг, 8 ноября 2018 г.

Ключевое слово This и его применение в Классе\Пользовательской структуре

Я заметил,что семантика работы ключевого слова "this" в пользовательских структурах и классах,кардинально отличается. К примеру,в структуре мы можем сделать что то подобное :
struct MyStruct { int x,y;
void Reset() { this = new MyStruct(); // удаляем предыдущую структуру и создаем новую О_О } }
Хотелось бы увидеть всю разницу ключевого слова This, между структурой и классом,а так же узнать, что там твориться под капотом.


Ответ

Самое главное различие состоит в том, что переменная this для структурного типа должна быть явно присвоенной в конструкторе структуры.
Переменная структурного типа, а this для структур является переменной структурного типа, считается явно присвоенной , если каждое из ее полей является явно присвоенным
Как это сказывается на структурах?
Это сказывается на работе конструкторов. Рассмотрите следующий пример объявления структуры
struct EvenOdd { int x, y; void make_even() { x &= ~0 << 1; }
void make_odd() { y |= 1; }
public EvenOdd( int x, int y ) { this.x = x; make_even(); this.y = y; make_odd(); } }
Для этого объявления структуры компилятор выдаст сообщение об ошибке,
Ошибка CS0188 Невозможно использовать объект this, пока не будут назначены все его поля.
потому что в точке вызова метода make_even this еще не является явно присвоенной, так как член данных структуры y еще не был инициализирован.
После выхода из конструктора переменная this считается явно присвоенной
Вы можете сделать предыдущий конструктор структуры валидным посредством предварительного вызова конструктора по умолчанию
public EvenOdd( int x, int y ) : this() { this.x = x; make_even(); this.y = y; make_odd(); }
В этом случае внутри тела конструктора с параметрами переменная this уже будет явно присвоенной
Если же вы измените это объявление на объявление класса, то никаких проблем с this, где this уже не переменная, а значение, не будет, и данный класс будет успешно компилироваться.
class EvenOdd { int x, y; void make_even() { x &= ~0 << 1; }
void make_odd() { y |= 1; }
public EvenOdd( int x, int y ) { this.x = x; make_even(); this.y = y; make_odd(); } }

Комментариев нет:

Отправить комментарий