Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Теоретический_курс.doc
Скачиваний:
36
Добавлен:
10.11.2019
Размер:
7.68 Mб
Скачать

5. Конструкторы экземпляра класса и статические члены класса

Как уже говорилось выше, в C# конструкторы вызываются при создании объекта (конструктор экземпляра) или когда CLR загружает тип (статический конструктор). У каждого класса по умолчанию всегда есть конструктор, даже если он не описан явно. Например:

class MyClass

{

}

class MyClass

{

public MyClass()

{

}

}

В данном случае, здесь два класса и оба имеют одинаковый конструктор. Конструкторы нужны для инициализации объекта. В них может находиться какой-то код, который автоматически будет срабатывать при создании объекта (если конструктор не является статическим). Конструктор всегда имеет такое же название, как и имя класса и ничего не возвращает.

Конструкторы могут быть перегружены и принимать параметры:

class MyClass

{

public MyClass()

{

// Выполнили действия по инициализации

}

public MyClass(int x)

{

// Выполнили действия по инициализации

}

}

В примере выше у класса есть два конструктора, один пустой (так называемый конструктор по умолчанию), другой принимает целочисленное значение, которые может быть использовано.

Конструкторы экземпляра срабатывают при создании нового объекта:

MyClass cl = new MyClass();

MyClass ck = new MyClass(1);

В первом случае сработал конструктор без аргументов, во втором, в качестве аргумента была передана единица. Всё описанное выше относится к конструкторам экземпляра.

В случае, когда экземпляр класса не создаётся, но всё же требуется вызвать конструктор и произвести какие-то действия, используется статический конструктор (static) для статических членов класса:

class MyClass

{

static MyClass()

{

// Выполнили действия по инициализации

// Этот конструктор не обязательно описывать, если он не нужен

}

public static int Sum(int x, int y)

{

return x + y;

}

}

В этом случае конструктор сработает при первом обращении к типу.

Для объявления статических методов (а также переменных, свойств и событий) класса используется ключевое слово static перед возвращаемым типом члена, как показано в следующем примере:

public class Automobile

{

public static int NumberOfWheels = 4;

public static int SizeOfGasTank

{

get

{

return 15;

}

}

public static void Drive() { }

public static event EventType RunOutOfGas;

// Прочие статические и нестатические члены класса

}

Однако существуют небольшие и существенные отличия статического конструктора от обычного конструктора. Статический конструктор:

  • не требует модификаторов доступа и не может принимать параметры. Т. е. используется только так, как описано в примере выше;

  • вызывается при создании первого экземпляра;

  • нет возможности вызывать статический конструктор напрямую;

  • вызывается только один раз, в независимости, сколько экземпляров было создано и остаётся в памяти домена приложения до закрытия программы;

  • может быть описан в классе только один раз;

  • если в классе есть конструктор экземпляра, то статический конструктор вызовется раньше конструктора экземпляра;

  • статический конструктор может быть использован только для инициализации статических данных или выполнения каких-то действий (например, запись в строковую переменную, что был выполнен доступ к текущему классу).

int sum = MyClass.Sum(3, 2);

В результате переменная sum будет содержать значение 5 и в тоже время, выполнится код в конструкторе public static MyClass() до выполнения метода Sum. Другими словами, любой конструктор выполнится, до того момента, когда будут использоваться возможности класса. Как можно заметить, все конструкторы отмечаются как public, что делает возможность создавать экземпляры с помощью оператора new. Если вместо public, написать private, то таким образом закроется возможность создавать новые экземпляры (будет вызван закрытый конструктор). Чаще всего эта возможность используется, когда класс содержит только статические свойства и методы.

Существуют ещё два модификатора: protected и internal. Если член класса имеет модификатор public, то, как уже говорилось выше, к нему можно обращаться из любого места программы через точку. Если private, то только в пределах данного класса. Protected — запрещает использование члена в классе-наследнике. Internal — служит для ограничения области видимости в пределах нескольких сборок. Открытым интерфейсом называется совокупность типов имеющих модификатор public.

Для самих классов доступно только два модификатора: public и internal. Их действие аналогично действиям для членов класса.

Такой вот код вызовет ошибку:

class MyClass

{

static MyClass()

{

//Выполнили действия по инициализации

//Этот конструктор не обязательно описывать, если он не нужен

}

private MyClass()

{

//Никогда не вызовется

}

public static int Sum(int x, int y)

{

return x + y;

}

}

...

private void button1_Click(object sender, EventArgs e) // Пусть это будет нажатие кнопки button1 на форме

{

MyClass cl = new MyClass(); // Неправильно (вызовет ошибку, нельзя создать экземпляр класса из-за уровня защиты private)

int sum = MyClass.Sum(3,2); // Правильно (вызываем статический метод из нестатического класса)

MessageBox.Show(sum.ToString());

}

Статический конструктор может быть описан вместе с конструктором экземпляра, как это показано в примере выше. С точки зрения производительности, статические конструкторы медленнее своих братьев — конструкторов экземпляра. Использование явных статических конструкторов приводит к генерации менее производительного кода.