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
49.3k16 gold badges121 silver badges199 bronze badges
asked Apr 30, 2014 at 15:07
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.
answered Apr 30, 2014 at 15:08
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
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
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 допишем наш класс следующим образом:
- добавим статическую переменную
int ordNumber
в класс, значение которой по умолчанию будет равен нулю; - создадим статический метод, который будет возвращать значение
ordNumber
. - в конструкторе класса переменная
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
. Такие конструкторы обладают следующими особенностями:
- статический конструктор нельзя перегрузить
- статический конструктор не принимает никаких параметров
- статический конструктор выполняется один раз вне зависимости от того сколько объектов данного класса создано
- исходя из п.3, статический конструктор не должен иметь никаких модификаторов доступа — он вызывается автоматически при создании первого объекта или при первом обращении к статическому члену класса.
Например, в нашем классе можно определить вот такой статический конструктор:
class Building { static int ordNumber; //статический конструктор static Building() { ordNumber = 0; } }
Статические классы
Кроме того, что вы можете объявлять статические члены класса (поля, методы, свойства), в C# вы можете объявлять статическими целые классы. Объявить статический класс можно так:
static class SomeClass { }
при этом следует помнить, что если к классу применяется ключевое слово static
, все члены этого класса должны быть static
. Где вы можете встретить статический класс C#? Одним из самых показательных примеров может быть тот самый класс Console
, методами которого мы пользуемся с самого начала знакомства с языком C#. Чтобы мы не считывали или не записывали в консоль — мы всегда используем статические методы статического класса (не создаем объект типа Console
, а используем методы класса).
Итого
Сегодня мы познакомились с ключевым словом (модификатором) static
, которое позволяет создавать члены класса, не относящиеся к конкретному объекту, а к типу данных (классу) в целом. С помощью static
можно объявлять поля,методы, свойства класса и объявлять целиком статические классы C#.
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.