Какая польза от статических конструкторов? - PullRequest
275 голосов
/ 22 декабря 2010

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

Ответы [ 9 ]

234 голосов
/ 22 декабря 2010

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

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

108 голосов
/ 22 декабря 2010

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

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

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

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

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

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

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

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

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

87 голосов
/ 24 ноября 2015

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

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

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;

    }
}

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

14 голосов
/ 17 февраля 2015

1. Он может получить доступ только к статическим членам класса.

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

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

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

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

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

9 голосов
/ 27 сентября 2013

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

5 голосов
/ 18 февраля 2017

Зачем и когда мы создадим статический конструктор ...?

Одна специфическая причина использования статического конструктора заключается в создании 'super 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's 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 (потому что для этого требуются постоянные значения).

2 голосов
/ 27 мая 2016

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

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

0 голосов
/ 05 октября 2018

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
0 голосов
/ 28 июля 2017

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

Источник: http://www.c -sharpcorner.com / article / static-constructor-in-C-Sharp-and-их-использования /

...