2010-09-03 61 views
4

我有一个简单的类,它有一个静态构造函数和一个实例构造函数。现在,当我初始化类时,调用了静态和实例构造函数。只有静态在应用程序域中被引用一次。我可以再次调用相同的类初始化和静态构造函数初始化吗?我已经尝试过,但没有发生?有没有什么办法可以在类中使用垃圾回收之后,在main()方法中再次调用静态构造函数。C#静态垃圾收集器?

下面是代码:

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

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

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

现在主要方法调用:

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

输出:

静态构造函数称为 实例构造称为 实例构造称为

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

谢谢。 Pal

+2

为什么你在地球上编写代码? – 2010-09-03 12:18:12

+1

@Developer:因为他可以:-D – abatishchev 2010-09-03 12:24:55

+0

@Developer ARt,请告诉我为什么我们不能在一个类中有多个静态构造函数?为什么:-D ...? – 2010-09-03 12:31:23

回答

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 
2

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

1

构造函数的要点是将事物放入所需的初始有效状态。

实例构造函数将实例放入初始有效状态。

带参数的实例构造函数将实例放入一个反映其参数的初始有效状态。

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

理想情况下,所有方法都将使对象和类型处于有效状态,但构造方法在负责将其置于一个状态中时有所不同。因此,任何试图调用构造函数两次的尝试都是错误的,因为“再次将其置于初始有效状态”不是您可以在逻辑上做两次(“初始”和“再次”不能很好地工作同一条款)。编译器(它拒绝编译)和语言(无法表达这一点)帮助我们做这样的事情。而且,作为一个逻辑上的不可能性,它并不是你实际上想要做的事情(当然,我可以画出一个三角形,但只能说我做了)。这表明您正在使用您的构造函数来执行除设置初始有效状态之外的其他操作。

除了在构造函数中建立这样的有效状态之外,做其他任何事情都是(尽量不这样做)充其量只是最优化,通常是严重的设计缺陷,很可能(更糟糕的是,因为它更长时间不固定)尝试优化,这是一个严重的设计缺陷。

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

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