Console.WriteLine("t2.x,
t2.y:
" +
t2.x
+
", " +
t2.y);
Console.WriteLine("t3.x,
t3.y:
" +
t3.x
+
", " +
t3.y);
}
}
Выполнение этого кода приводит к следующему результату.
В конструкторе XYCoord(int, int)
В конструкторе XYCoord()
В конструкторе XYCoord(int, int)
В конструкторе XYCoord(int, int)
В конструкторе XYCoord(obj)
tl.x, tl.y: 0, 0
t2.x, t2.у: 8, 9
t3.x, t3.у: 8, 9
Код в приведенном выше примере работает следующим образом. Единственным конструктором, фактически инициализирующим поля х и у в классе XYCoord
, является конструктор XYCoord(int, int).
А два других конструктора просто вызывают этот конструктор с помощью ключевого слова this
. Например, когда создается объект t1, то вызывается его конструктор XYCoord(),
что приводит к вызову this(0, 0),
который в данном случае преобразуется в вызов конструктора XYCoord(0, 0)
. То же самое происходит и при создании объекта t2.
Вызывать перегружаемый конструктор с помощью ключевого слова this
полезно, в частности, потому, что он позволяет исключить ненужное дублирование кода. В приведенном выше примере нет никакой необходимости дублировать во всех трех конструкторах одну и ту же последовательность инициализации, и благодаря применению ключевого слова this
такое дублирование исключается. Другое преимущество организации подобного вызова перезагружаемого конструктора заключается в возможности создавать конструкторы с задаваемыми "по умолчанию" аргументами, когда эти аргументы не указаны явно. Ниже приведен пример создания еще одного конструктора XYCoord
.
public XYCoord(int х) : this(х, х) { }
По умолчанию в этом конструкторе для координаты у автоматически устанавливается то же значение, что и для координаты у. Конечно, пользоваться такими конструкциями с задаваемыми "по умолчанию" аргументами следует благоразумно и осторожно, чтобы не ввести в заблуждение пользователей классов.
Инициализаторы объектов предоставляют еще один способ создания объекта и инициализации его полей и свойств. (Подробнее о свойствах речь пойдет в главе 10.) Если используются инициализаторы объектов, то вместо обычного вызова конструктора класса указываются имена полей или свойств, инициализируемых первоначально задаваемым значением. Следовательно, синтаксис инициализатора объекта предоставляет альтернативу явному вызову конструктора класса. Синтаксис инициализатора объекта используется главным образом при создании анонимных типов в LINQ-выражениях. (Подробнее об анонимных типах и LINQ-выражениях — в главе 19.) Но поскольку инициализаторы объектов можно, а иногда и должно использовать в именованном классе, то ниже представлены основные положения об инициализации объектов.
Обратимся сначала к простому примеру.
// Простой пример, демонстрирующий применение инициализаторов объектов.
using System;
class MyClass {
public int Count;
public string Str;
}
class ObjInitDemo {
static void Main() {
// Сконструировать объект типа MyClass, используя инициализаторы объектов.
MyClass obj = new MyClass {
Count = 100, Str = "Тестирование"
};
Console.WriteLine(obj.Count + " " + obj.Str);
}
}
Выполнение этого кода дает следующий результат.
100 Тестирование
Как показывает результат выполнения приведенного выше кода, переменная экземпляра obj.Count
инициализирована значением 100, а переменная экземпляра obj.Str
— символьной строкой "Тестирование". Но обратите внимание на то, что в классе MyClass
отсутствуют явно определяемые конструкторы и не используется обычный синтаксис конструкторов. Вместо этого объект obj
класса MyClass
создается с помощью следующей строки кода.
MyClass obj = new MyClass { Count = 100, Str = "Тестирование" };
В этой строке кода имена полей указываются явно вместе с их первоначальными значениями. Это приводит к тому, что сначала конструируется экземпляр объекта типа MyClass
(с помощью неявно вызываемого по умолчанию конструктора), а затем задаются первоначальные значения переменных Count и Str
данного экземпляра.
Читать дальше