Поиск

Инициализаторы конструкторов

Во всех конструкторах С#, кроме System.Object, конструкторы базового класса вызываются прямо перед исполнением первой строки конструктора. Эти инициализаторы конструкторов позволяют задавать класс и подлежащий вызову конструктор. Они бывают двух видов.

  • Инициализатор в виде base(...) активизирует конструктор базового класса текущего класса.
  • Инициализатор в виде this(...) позволяет текущему базовому классу вызвать другой конструктор, определенный в нем самом. Это полезно, когда вы перегрузили несколько конструкторов и хотите быть уверенными, что всегда будет вызван конструктор по умолчанию. О перегруженных методах см. главу 6, здесь же мы приведем их краткое и не совсем точное определение: перегруженными называются два и более методов с одинаковым именем, но с различными списками аргументов.

Чтобы увидеть порядок событий в действии, обратите внимание на следующий код: он сначала исполнит конструктор класса А, а затем конструктор класса В:

using System;
class A
<
public A() {
Console.WriteLine("A"); } }
class В : А
<
public B() {
Console.WriteLine("B"); } }
class DefaultlnitializerApp {
public static void MainQ
{
В b = new B();
} }

Этот код — функциональный эквивалент следующего, где производится явный вызов конструктора базового класса:

using System;
class A {
public A()
{
Console.WriteLine("A");
} }
class В : A /
{
public BO : baseO
{
Console.WriteLine("B");
} }
class BaseDefaultlnitializerApp <
public static void Main()
{
В b = new BO;
} }

А теперь рассмотрим более удачный пример ситуации, когда выгодно использовать инициализаторы конструкторов. У меня опять два класса: А и В. На этот раз у класса А два конструктора, один из них не требует аргументов, а другой принимает аргумент типа int. У класса В один конструктор, принимающий аргумент типа int. При создании класса В возникает проблема. Если запустить следующий код, будет вызван конструктор класса А, не принимающий аргументов:

using System;
class A <
public АО {
Console.WriteLine("A"); >
public A(int foo) {
Console.WriteLineC'A = {0}", foo); } }
class В : А {
public B(int foo) {
Console.WriteLineC'B = {0}", foo);
} }
class DerivedlnitializeMApp {
public static void MainQ
{
В Ь = new B(42);
} }

Как же гарантировать, что будет вызван именно нужный конструктор класса А1 Явно указав компилятору, какой конструктор в инициализаторе должен быть вызван первым, скажем, так:

using System;
class A {
public A()
{
Console. Writel_ine( "A");
}
public A(int foo) {
Console.WriteLineC'A = {0}", foo); } >
class В : А {
public B(int foo) ; base(foo)
{
Console.WriteLine("B = {0}". foo);
} >
class DerivedInitializer2App {
public static void Main()
< / В b = new B(42); /
} /
} /

ПРИМЕЧАНИЕ В отличие от Visual C++ для обращения к членам экземпляров вы не можете использовать инициализаторы конструкторов, кроме конструкторов текущего класса.