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

When I have a static field in my class:

public static int Counter = 0;

With a static constructor:

static Class() { 
    Counter++; 
}

When I create an object of this class and check Class.Counter it shows me 1 which is correct.

But when I create another object of the same class, Class.Counter remains 1.

Why is that?

vgru's user avatar

vgru

49.3k16 gold badges121 silver badges199 bronze badges

asked Apr 30, 2014 at 15:07

Krzysztof Borowy's user avatar

6

Because the static constructor is executed only once.

From C# Specification:

The static constructor for a class executes at most once in a given application domain. The execution of a static constructor is triggered by the first of the following events to occur within an application domain:

  • An instance of the class is created.
  • Any of the static members of the class are referenced.

Community's user avatar

answered Apr 30, 2014 at 15:08

Selman Genç's user avatar

Selman GençSelman Genç

99.4k13 gold badges118 silver badges183 bronze badges

2

That is because you are incrementing your counter in static constructor, and it will be executed just once.

static constructor C# — MSDN

A static constructor is used to initialize any static data, or to
perform a particular action that needs to be performed once only.
It is called automatically before the first instance is created or any
static members are referenced.

You can fix it by incrementing in instance constructor like:

class Class
{
    public static int counter = 0;

    public Class()
    {
        counter++;
    }
}

For thread-safety use Interlocked.Increment(ref counter); instead of counter++

answered Apr 30, 2014 at 15:09

Habib's user avatar

1

Selman22 has it correct, here is a little more detail:

From MSDN

A static constructor is used to initialize any static data, or to perform a particular action that needs to be performed once only.
It is called automatically before the first instance is >created or any static members are referenced.

Static constructors have the following properties:

  • A static constructor does not take access modifiers or have parameters.
  • A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced.
  • A static constructor cannot be called directly.
  • The user has no control on when the static constructor is executed in
    the program.
  • A typical use of static constructors is when the class is using a log
    file and the constructor is used to write entries to this file.
  • Static constructors are also useful when creating wrapper classes for
    unmanaged code, when the constructor can call the LoadLibrary method.

If a static constructor throws an exception, the runtime will not invoke it a second time, and the type will remain uninitialized for the lifetime of the application domain in which your program is running.

Reference url: http://msdn.microsoft.com/en-us/library/k9x6w0hc.aspx

answered Apr 30, 2014 at 15:12

Pseudonym's user avatar

PseudonymPseudonym

2,0542 gold badges17 silver badges38 bronze badges

Static constructors are constructors that are executed only ONCE when the class is loaded. Regular (non-static) constructors are executed every time an object is created.

Take a look at this example:

public class A
{
     public static int aStaticVal;
     public int aVal;

     static A() {
         aStaticVal = 50;
     }

     public A() {
         aVal = aStaticVal++;
     }
}

And consider this code:

A a1 = new A();
A a2 = new A();
A a3 = new A();

Here, static constructor will be called first and only once during the execution of the program. While regular constructor will be called three times (once for each object instantiation).

static constructors are usually used to do initialization of static fields for example, assigning an initial value to static fields.. Do keep in mind that you will only be able to access static members (methods, properties and fields) on static constructors.

If you need to «execute the static constructor multiple times», you can’t do that. Instead, you can put the code you want to run «multiple times» in a static method and call it whenever you need. Something like:

public class A {
    public static int a, b;
    static A() {
         A.ResetStaticVariables();
    }
    public static void ResetStaticVariables() {
        a = b = 0;
    }
}

Содержание

  • Ключевое слово static
  • Использование методов C# без  создания объекта
  • Инициализация статических полей
    • Присвоение значения по умолчанию
    • Использование статического конструктора
  • Статические классы
  • Итого

уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

На данный момент мы уже знаем достаточно много ключевых слов, в том числе и такие как private, public, internal и так далее, позволяющие указать уровень доступа членов класса. И, несмотря на то, что с ключевым словом static мы уже встречались не раз, однако, вся его мощь чувствуется именно при работе с классами в языке C#.

Ключевое слово static может использоваться в различных контекстах, однако сегодня речь пойдет о его использовании именно в классах C#. В русской литературе по программированию на языке C# можно встретить такие определения, как «статичный», «статический» и так далее. В любом случае, это означает, что какой-либо член класса (свойство, метод) определен с атрибутом static.

В документации Microsoft по языку C# дословно сказано следующее:

Модификатор static используется для объявления статического члена, принадлежащего собственно типу, а не конкретному объекту.Microsoft

Посмотрим, что это означает на практике.

Использование методов C# без  создания объекта

До сих пор, при работе с классом Building, который мы создавали здесь, мы вызывали методы только после того, как был создан объект типа Building, например:

//создаем объект
Building building = new Building { Width = 40, Length = 30, Height = 5 };
//вызываем метод
building.ExpandSize(2, 2, 2);

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

  1. добавим статическую переменную int ordNumber в класс, значение которой по умолчанию будет равен нулю;
  2. создадим статический метод, который будет возвращать значение ordNumber.
  3. в конструкторе класса переменная ordNumber будет увеличиваться на единицу.

Должен получиться вот такой код:

class Building
{
    static int ordNumber = 0;

    static public int GetOrdNumber()
    {
        return ordNumber;
    }

    public Building()
    {
        width = 10;
        length = 10;
        height = 2;
        ordNumber++;
    }
}

Теперь посмотрим что будет выводиться в консоли, если выполнить вот такой код:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(Building.GetOrdNumber());//воспользовались статическим методом
        Building building1 = new Building();       //создаем новый объект
        Console.WriteLine(Building.GetOrdNumber());//воспользовались статическим методом
        Building building2 = new Building();       //создаем новый объект
        Console.WriteLine(Building.GetOrdNumber());//воспользовались статическим методом
        Building building3 = new Building();       //создаем новый объект 
        Console.WriteLine(Building.GetOrdNumber());//воспользовались статическим методом
    }
}

Здесь мы вызываем статический метод каждый раз после создания очередного объекта.  При этом обратите внимание, что мы всегда обращаемся к статическому методу,указывая тип данных, а не ссылку на объект (по другому обратиться к статическому методу в C# нельзя). В консоли вы увидите следующий вывод:

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

НЕстатические

переменные

у каждого объекта свои, статические

переменные

— общие для всех объектов класса. На уровне памяти для каждой статической переменной выделяется один участок памяти для всех объектов.

Инициализация статических полей

Чтобы инициализировать статическое поле в C# можно использовать такие варианты:

Присвоение значения по умолчанию

Например,как мы это сделали в нашем классе:

static int ordNumber = 0;

Использование статического конструктора

Наряду с обычными конструкторами в языке C# могут использоваться статические конструкторы, т.е конструкторы, имеющие модификатор static. Такие конструкторы обладают следующими особенностями:

  1. статический конструктор нельзя перегрузить
  2. статический конструктор не принимает никаких параметров
  3. статический конструктор выполняется один раз вне зависимости от того сколько объектов данного класса создано
  4. исходя из п.3, статический конструктор не должен иметь никаких модификаторов доступа — он вызывается автоматически при создании первого объекта или при первом обращении к статическому члену класса.

Например, в нашем классе можно определить вот такой статический конструктор:

class Building
{
    static int ordNumber;
    //статический конструктор
    static Building()
    {
        ordNumber = 0;
    }
}

Статические классы

Кроме того, что вы можете объявлять статические члены класса (поля, методы, свойства), в C# вы можете объявлять статическими целые классы. Объявить статический класс можно так:

static class SomeClass
 {

 }

при этом следует помнить, что если к классу применяется ключевое слово static, все члены этого класса должны быть static.  Где вы можете встретить статический класс C#? Одним из самых показательных примеров может быть тот самый класс Console, методами которого мы пользуемся с самого начала знакомства с языком C#.  Чтобы мы не считывали или не записывали в консоль — мы всегда используем статические методы статического класса (не создаем объект типа Console, а используем методы класса).

Итого

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

уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

Понравилась статья? Поделить с друзьями:
  • Столичная автобусная компания официальный сайт купить билет на автобус
  • Федеральная сетевая компания единой энергетической системы руководство
  • Стоматологическая поликлиника 48 беляево часы работы платное отделение
  • Федеральное казенное учреждение единый расчетный центр мо рф реквизиты
  • Стратегия деятельности компании в целом по всем сферам ее деятельности