Выбрать главу

• Статический конструктор не имеет модификатора доступа и не может принимать параметры.

• Статический конструктор выполняется только один раз вне зависимости от количества создаваемых объектов заданного класса.

• Исполняющая система вызывает статический конструктор, когда создает экземпляр класса или перед доступом к первому статическому члену из вызывающего кода.

• Статический конструктор выполняется перед любым конструктором уровня экземпляра.

С учетом такой модификации при создании новых объектов SavingsAccount значения статических данных предохраняются, поскольку статический член устанавливается только один раз внутри статического конструктора независимо от количества созданных объектов.

Определение статических классов

Ключевое слово static допускается также применять прямо на уровне класса. Когда класс определен как статический, его экземпляры нельзя создавать с использованием ключевого слова new, и он может содержать только члены или поля данных, помеченные ключевым словом static. В случае нарушения этого правила возникают ошибки на этапе компиляции.

На заметку! Вспомните, что класс (или структура), который открывает доступ только к статической функциональности, часто называется обслуживающим классом. При проектировании обслуживающего класса рекомендуется применять ключевое слово static к самому определению класса.

На первый взгляд такое средство может показаться довольно странным, учитывая невозможность создания экземпляров класса. Тем не менее, в первую очередь класс, который содержит только статические члены и/или константные данные, не нуждается в выделении для него памяти. В целях иллюстрации определите новый класс по имени TimeUtilClass:

using System;

namespace StaticDataAndMembers

{

  // Статические классы могут содержать только статические члены!

  static class TimeUtilClass

  {

    public static void PrintTime()

      => Console.WriteLine(DateTime.Now.ToShortTimeString());

    public static void PrintDate()

      => Console.WriteLine(DateTime.Today.ToShortDateString());

  }

}

Так как класс TimeUtilClass определен с ключевым словом static, создавать его экземпляры с помощью ключевого слова new нельзя. Взамен вся функциональность доступна на уровне класса. Чтобы протестировать данный класс, добавьте к операторам верхнего уровня следующий код:

// Это работает нормально.

TimeUtilClass.PrintDate();

TimeUtilClass.PrintTime();

// Ошибка на этапе компиляции!

// Создавать экземпляры статического класса невозможно!

TimeUtilClass u = new TimeUtilClass ();

Console.ReadLine();

Импортирование статических членов с применением ключевого слова using языка C#

В версии C# 6 появилась поддержка импортирования статических членов с помощью ключевого слова using. В качестве примера предположим, что в файле C# определен обслуживающий класс. Поскольку в нем делаются вызовы метода WriteLine() класса Console, а также обращения к свойствам Now и Today класса DateTime, должен быть предусмотрен оператор using для пространства имен System. Из-за того, что все члены упомянутых классов являются статическими, в файле кода можно указать следующие директивы using static:

// Импортировать статические члены классов Console и DateTime.

using static System.Console;

using static System.DateTime;

После такого "статического импортирования" в файле кода появляется возможность напрямую применять статические методы классов Console и DateTime, не снабжая их префиксом в виде имени класса, в котором они определены. Например, модифицируем наш обслуживающий класс TimeUtilClass, как показано ниже:

static class TimeUtilClass

{

 public static void PrintTime()

    => WriteLine(Now.ToShortTimeString());

  public static void PrintDate()

    => WriteLine(Today.ToShortDateString());

}

В более реалистичном примере упрощения кода за счет импортирования статических членов мог бы участвовать класс С#, интенсивно использующий класс System.Math (или какой-то другой обслуживающий класс). Поскольку этот класс содержит только статические члены, отчасти было бы проще указать для него оператор using static и затем напрямую обращаться членам класса Math в своем файле кода.