C#静态垃圾收集器?

时间:2010-09-03 12:15:24

标签: c# .net constructor garbage-collection static-constructor

我有一个简单的类,它有一个静态构造函数和一个实例构造函数。现在,当我初始化类时,调用静态和实例构造函数。在应用程序域中只引用一次静态。我可以再次调用相同的类初始化和静态构造函数再次初始化吗?我试过但它没有发生?在类上使用垃圾收集后,有没有办法在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();
}

输出:

  

调用静态构造函数   实例构造函数调用   实例构造函数名为

现在静态没有再次调用。因为它在应用程序域中被调用一次。但他们是否可以在不卸载应用程序域的情况下再次调用它。我们可以在这里使用GC类吗?

感谢。 帕尔

3 个答案:

答案 0 :(得分:8)

除非你用反射来刺激它,否则静态构造函数(或更一般地说,类型初始值设定项)每个AppDomain每个具体类只执行一次。

请注意,对于泛型,使用不同的类型参数,您将获得不同的具体类:

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

答案 1 :(得分:2)

不可能。 CLR保留一个内部状态位,用于跟踪类型初始值设定项是否已启动。它无法再次运行。该状态位确实作为AppDomain状态的一部分存储在加载程序堆中。解决方法很简单,只需在类中添加静态方法即可。

答案 2 :(得分:1)

构造函数的目的是将事物置于所需的初始有效状态。

实例构造函数将实例置于初始有效状态。

带参数的实例构造函数将实例置于反映其参数的初始有效状态。

静态构造函数将类型置于初始有效状态。例如。初始化类的静态方法使用的静态成员或由所有实例共享的静态成员。

理想情况下,所有方法都会将对象和类型保留为有效状态,但构造函数的不同之处在于首先要将其置于一个中。

因此,任何两次调用构造函数的尝试都是错误的,因为“将它再次置于初始有效状态”并不是你可以在逻辑上做两次的事情(“初始”和“再次”不能在同一条款)。编译器(在它拒绝编译)和语言(无法表达这一点)的帮助下我们做了这样的事情。

而且,在逻辑上是不可能的,这不是你真正想要做的事情(好吧,我可以想要绘制一个超过3个边的三角形,但只是说我做了)。这表明您正在使用构造函数执行除设置初始有效状态之外的其他操作。

除了在构造函数中建立这样一个有效状态之外做任何其他事情(因为没有这样做)充其量只是一个优化,通常是一个严重的设计缺陷,并且很可能(更糟的是因为它不再固定)优化确实是一个严重的设计缺陷。

您尝试优化实际上是一个设计缺陷的一个迹象是希望不止一次调用静态构造函数,或者在同一个对象上多次调用实例构造函数。

确定所需的可重复行为,将其移动到单独的方法中,并根据需要从构造函数和其他地方调用它。然后仔细检查你的设计逻辑,因为在课堂设计中发现这是一个非常严重的错误,并暗示你有更深层次的问题。