C # статический сборщик мусора? - PullRequest
4 голосов
/ 03 сентября 2010

У меня есть простой класс, который имеет статический конструктор и конструктор экземпляра.Теперь, когда я инициализировал класс, вызывается статический конструктор и конструктор экземпляра.Только статический указывается один раз в домене приложения.Могу ли я снова вызвать ту же инициализацию класса и статический конструктор снова?Я пытался, но этого не случилось?Есть ли способ, как мы можем снова вызвать статический конструктор в методе main () после использования сборки мусора в классе.

Вот код:

public class Employee
{
    public Employee()
    {
        Console.WriteLine("Instance constructor called");   
    }

    static Employee()
    {
        Console.WriteLine("Static constructor called");   
    }

    ~Employee()
     {
        //Dispose();
     }
}

Теперь в вызове метода main:

static void Main(string[] args)
{
    Employee emp = new Employee();
    Employee emp = new Employee();
}

Выходные данные:

Статический конструктор, называемый конструктором Instance, называемый конструктором Instance, называемый

Теперь статический элемент больше не вызывается.Потому что он вызывается один раз в домене приложения.Но есть ли их способ, которым мы могли бы вызвать его снова, не выгружая домен приложения.Можем ли мы использовать класс GC здесь?

Спасибо.Pal

Ответы [ 3 ]

8 голосов
/ 03 сентября 2010

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

Обратите внимание, что для обобщенных типов, используя аргументы разных типов, вы получите разные конкретные классы:

public class Foo<T>
{
    Foo()
    {
        Console.WriteLine("T={0}", typeof(T));
    }
    public static void DummyMethod() {}
}
...
Foo<int>.DummyMethod(); // Executes static constructor first
Foo<string>.DummyMethod(); // Executes static constructor first
Foo<string>.DummyMethod(); // Type is already initialized; no more output
2 голосов
/ 03 сентября 2010

Не возможно. CLR хранит внутренний бит состояния, который отслеживает, был ли запущен инициализатор типа. Это не может бежать снова. Этот бит состояния действительно сохраняется в куче загрузчика как часть состояния AppDomain. Обходной путь прост, просто добавьте статический метод в класс.

1 голос
/ 03 сентября 2010

Задача конструктора - привести вещи в желаемое начальное допустимое состояние.

Конструктор экземпляра переводит экземпляр в исходное допустимое состояние.

Конструктор экземпляра, который принимает аргументы, переводит экземпляр в исходное допустимое состояние, которое отражает его аргументы.

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

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

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

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

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

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

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

...