// Вывести текущую процентную ставку.
Console.WriteLine("Interest Rate is: {0}", SavingsAccount.GetInterestRate());
// Попытаться изменить процентную ставку через свойство.
SavingsAccount.SetInterestRate(0.08);
// Создать второй объект счета.
SavingsAccount s2 = new SavingsAccount(100);
// Должно быть выведено 0.08, не так ли?
Console.WriteLine("Interest Rate is: {0}", SavingsAccount.GetInterestRate());
Console.ReadLine();
При выполнении этого кода вы увидите, что переменная currInterestRate
SavingsAccount
, и она всегда установлена в 0.04
. Очевидно, что установка значений статических данных в нормальном конструкторе уровня экземпляра сводит на нет все их предназначение. Когда бы ни создавался новый объект, данные уровня класса сбрасываются! Один из подходов к установке статического поля предполагает применение синтаксиса инициализации членов, как делалось изначально:class SavingsAccount
{
public double currBalance;
// Статические данные.
public static double currInterestRate = 0.04;
...
}
Такой подход обеспечит установку статического поля только один раз независимо от того, сколько объектов создается. Но что, если значение статических данных необходимо получать во время выполнения? Например, в типичном банковском приложении значение переменной, представляющей процентную ставку, будет читаться из базы данных или внешнего файла. Решение задач подобного рода обычно требует области действия метода, такого как конструктор, для выполнения соответствующих операторов кода.
По этой причине язык C# позволяет определять статический конструктор, который дает возможность безопасно устанавливать значения статических данных. Взгляните на следующее изменение в коде класса:
class SavingsAccount
{
public double currBalance;
public static double currInterestRate;
public SavingsAccount(double balance)
{
currBalance = balance;
}
// Статический конструктор!
static SavingsAccount()
{
Console.WriteLine("In static ctor!");
currInterestRate = 0.04;
}
...
}
Выражаясь просто, статический конструктор представляет собой специальный конструктор, который является идеальным местом для инициализации значений статических данных, если их значения не известны на этапе компиляции (например, когда значения нужно прочитать из внешнего файла или базы данных, сгенерировать случайные числа либо получить значения еще каким-нибудь способом). Если вы снова запустите предыдущий код, то увидите ожидаемый вывод. Обратите внимание, что сообщение "In static ctor!"
***** Fun with Static Data *****
In static ctor!
Interest Rate is: 0.04
Interest Rate is: 0.08
Ниже отмечено несколько интересных моментов, касающихся статических конструкторов.
• В отдельно взятом классе может быть определен только один статический конструктор. Другими словами, перегружать статический конструктор нельзя.
• Статический конструктор не имеет модификатора доступа и не может принимать параметры.
• Статический конструктор выполняется только один раз вне зависимости от количества создаваемых объектов заданного класса.
• Исполняющая система вызывает статический конструктор, когда создает экземпляр класса или перед доступом к первому статическому члену из вызывающего кода.
• Статический конструктор выполняется перед любым конструктором уровня экземпляра.
С учетом такой модификации при создании новых объектов SavingsAccount
Определение статических классов