4

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

谢谢。朋友

4

3 回答 3

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
于 2010-09-03T12:17:43.120 回答
2

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

于 2010-09-03T13:33:24.143 回答
1

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

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

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

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

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

因此,任何两次调用构造函数的尝试都是错误的,因为“再次将其置于初始有效状态”不是您可以在逻辑上执行两次的操作(“初始”和“再次”在同一子句中效果不佳) . 编译器(拒绝编译)和语言(无法表达)帮助我们做这样的事情。

而且,作为一个逻辑上的不可能,这不是你真正想做的事情(好吧,我可以想画一个超过 3 个边的三角形,但只是说我做了)。这表明您正在使用构造函数来做一些事情,而不是设置初始有效状态。

除了在构造函数中建立这样一个有效状态之外,做任何其他事情(因为没有这样做)充其量是一种优化,通常是一个严重的设计缺陷,而且很可能(更糟糕的是,因为它的未修复时间更长)尝试的优化是真的是一个严重的设计缺陷。

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

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

于 2010-09-03T13:42:45.893 回答