Каково использование статических конструкторов?

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

Ответ 1

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

Он запускается автоматически по времени выполнения при первой необходимости (точные правила там сложны (см. "beforefieldinit" ) и тонко изменяются между CLR2 и CLR4). Если вы не злоупотребляете отражением, гарантированно будет работать не более одного раза (даже если два потока прибудут в одно и то же время).

Ответ 2

Из Статические конструкторы (Руководство по программированию на С#):

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

Статические конструкторы имеют следующие Свойства:

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

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

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

  • Пользователь не может контролировать, когда статический конструктор выполняется в программе.

  • Типичное использование статических конструкторов - это когда класс использует файл журнала, а конструктор используется для записи записей в этот файл.

  • Статические конструкторы также полезны при создании классов-оболочек для неуправляемого кода, когда конструктор может вызвать метод LoadLibrary.

Ответ 3

Статические конструкторы также очень полезны, когда у вас есть статические поля, которые полагаются друг на друга, так что порядок инициализации важен. Если вы запустите свой код с помощью форматирования/украшателя, который изменяет порядок полей, вы можете найти нулевые значения, в которых вы их не ожидали.

Пример: предположим, что у нас был этот класс:

class ScopeMonitor
{
    static string urlFragment = "foo/bar";
    static string firstPart= "http://www.example.com/";
    static string fullUrl= firstPart + urlFragment;
}

При доступе к fullUr это будет http://www.example.com/foo/bar".

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

class ScopeMonitor
{
    static string firstPart= "http://www.example.com/";
    static string fullUrl= firstPart + urlFragment;
    static string urlFragment = "foo/bar";
}

Теперь ваше значение fullUrl просто "http://www.example.com/", так как urlFragment не был инициализирован в момент установки fullUrl. Нехорошо. Таким образом, вы добавляете статический конструктор, чтобы позаботиться об инициализации:

class ScopeMonitor
{
    static string firstPart= "http://www.example.com/";
    static string fullUrl;
    static string urlFragment = "foo/bar";

    static ScopeMonitor()
    {
        fullUrl= firstPart + urlFragment;

    }
}

Теперь, независимо от того, в каком порядке у вас есть поля, инициализация всегда будет правильной.

Ответ 4

1.It может обращаться только к статическому члену (-ам) класса.

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

2. В статическом конструкторе не должно быть параметров (ы).

Причина: Поскольку он будет вызываться CLR, никто не сможет передать ему параметр. 3. Разрешен только один статический конструктор.

Причина. Перегрузка требует, чтобы два метода отличались в терминах определения метода/конструктора, что невозможно в статическом конструкторе.

4. Для него не должно быть модификатора доступа.

Причина: опять же причина того же вызова статического конструктора производится CLR, а не объектом, нет необходимости в модификаторе доступа к нему

Ответ 5

вы можете использовать статический конструктор для инициализации статических полей. Он работает в неопределенное время до использования этих полей. Документация Microsoft и многие разработчики предупреждают, что статические конструкторы на типе накладывают существенные накладные расходы.
Лучше всего избегать статических конструкторов для максимальной производительности.
update: вы не можете использовать более одного статического конструктора в одном классе, однако вы можете использовать другие конструкторы экземпляров с (максимальным) одним статическим конструктором.

Ответ 6

Почему и когда мы будем создавать статический конструктор...?

Одной из конкретных причин использования статического конструктора является создание класса "супер enum". Здесь (простой, надуманный) пример:

public class Animals
{
    private readonly string _description;
    private readonly string _speciesBinomialName;

    public string Description { get { return _description; } }
    public string SpeciesBinomialName { get { return _speciesBinomialName; } }

    private Animals(string description, string speciesBinomialName)
    {
        _description = description;
        _speciesBinomialName = speciesBinomialName;
    }

    private static readonly Animals _dog;
    private static readonly Animals _cat;
    private static readonly Animals _boaConstrictor;

    public static Animals Dog { get { return _dog; } }
    public static Animals Cat { get { return _cat; } }
    public static Animals BoaConstrictor { get { return _boaConstrictor; } }

    static Animals()
    {
        _dog = new Animals("Man best friend", "Canis familiaris");
        _cat = new Animals("Small, typically furry, killer", "Felis catus");
        _boaConstrictor = new Animals("Large, heavy-bodied snake", "Boa constrictor");
    }
}

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

Animals.Dog

Преимущество этого в регулярном enum заключается в том, что вы можете инкапсулировать соответствующую информацию легко. Один из недостатков заключается в том, что вы не можете использовать эти значения в операторе switch (потому что он требует постоянных значений).

Ответ 7

Статический конструктор

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

Ответ 8

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

Источник: http://www.c-sharpcorner.com/article/static-constructor-in-C-Sharp-and-their-usages/

Ответ 9

using System;
namespace Constructor
{
class Test
{
//Declaration and initialization of static data member 
private static int id = 5;
public static int Id
{
get
{
return id;
}
}
public static void print()
{
Console.WriteLine("Test.id = " + id);
}
static void Main(string[] args)
{
//Print the value of id 
Test.print();
}
}
}

In the above example, static data member <id> is declared and initialized in same line. So if you compile and run this program your output would look similar to this :

Test.id = 5

Lets create one more class similar to class Test but this time the value of its static data member would depend on the value of static data member <id> of class Test.id.

//File Name : Test1.cs
using System;
namespace Constructor
{
class Test1
{
private static int id ;
//Static constructor, value of data member id is set conditionally here. 
//This type of initialization is not possible at the time of declaration.
static Test1()
{
if( Test.Id < 10 )
{
id = 20;
}
else
{
id = 100; 
}
Console.WriteLine("Static<Class> Constructor for Class Test1 Called..");
}
public static void print()
{
Console.WriteLine("Test1.id = " + id);
}
static void Main(string[] args)
{
//Print the value of id 
Test1.print();
}
}
}

As you can see in the above static constructor, static data member <id> is initialized conditionally. This type of initialization is not possible at the time of declaration. This is where static constructor comes in picture