C# 静态垃圾收集器?
我有一个简单的类,它有一个静态构造函数和一个实例构造函数。现在,当我初始化类时,静态构造函数和实例构造函数都会被调用。在应用程序域中仅引用一次静态。我可以再次调用相同的类初始化和静态构造函数初始化吗?我已经尝试过,但没有发生?在类上使用垃圾回收后,有什么方法可以在 main() 方法中再次调用静态构造函数。
这是代码:
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 类吗?
谢谢。 朋友
I have a simple class which has a static constructor and a instance constructor. Now when i initialized the class , both static and instance constructor are called. Only static is referred once in a application domain . Can i again call the same class initialization and static constructor initialize again? I have tried but it didn't happen? Is there any way we can call static constructor again in main() method after using garbage collection on the class.
Here is the code:
public class Employee
{
public Employee()
{
Console.WriteLine("Instance constructor called");
}
static Employee()
{
Console.WriteLine("Static constructor called");
}
~Employee()
{
//Dispose();
}
}
Now in main method call:
static void Main(string[] args)
{
Employee emp = new Employee();
Employee emp = new Employee();
}
Output:
Static constructor called
Instance constructor called
Instance constructor called
Now the static didn't called again. Because it is called once in application domain. But is their any way we could call it again without unloading application domain. Can we use GC class over here?
Thanks.
Pal
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
除非您使用反射来刺激它,否则静态构造函数(或更一般地说,类型初始值设定项)仅在每个具体类、每个 AppDomain 中执行一次。
请注意,对于泛型,使用不同的类型参数,您将获得不同的具体类:
Unless you prod it with reflection, the static constructor (or more generally, the type initializer) is only executed once per concrete class, per AppDomain.
Note that for generics, using different type arguments you'll get different concrete classes:
不可能。 CLR 保留一个内部状态位来跟踪类型初始值设定项是否已启动。它无法再次运行。该状态位确实作为 AppDomain 状态的一部分存储在加载程序堆中。解决方法很简单,只需在类中添加一个静态方法即可。
Not possible. The CLR keeps an internal status bit that tracks whether the type initializer was started. It cannot run again. That status bit is indeed stored in the loader heap as part of the AppDomain state. The workaround is simple, just add a static method to the class.
构造函数的目的是将事物置于所需的初始有效状态。
实例构造函数将实例置于初始有效状态。
接受参数的实例构造函数将实例置于反映其参数的初始有效状态。
静态构造函数将类型置于初始有效状态。例如,初始化类的静态方法使用的静态成员或由所有实例共享的静态成员。
理想情况下,所有方法都会使对象和类型保持有效状态,但构造函数在首先负责将其变为有效状态方面有所不同。
因此,任何两次调用构造函数的尝试都是错误的,因为“再次将其置于初始有效状态”在逻辑上不是可以执行两次的事情(“初始”和“再次”在同一个子句中不能很好地工作) 。编译器(拒绝编译)和语言(无法表达这一点)帮助我们做这样的事情。
而且,从逻辑上讲,这并不是你真正想做的事情(好吧,我可以想画一个超过 3 条边的三角形,但只是说我做到了)。这表明您正在使用构造函数执行除设置初始有效状态之外的其他操作。
除了在构造函数中建立这样的有效状态之外,做任何其他事情充其量只是一种优化(如果没有这样做),通常是一个严重的设计缺陷,并且很可能(更糟糕的是,因为它未修复的时间更长)是一种尝试的优化,即确实是一个严重的设计缺陷。
表明您的优化尝试实际上是设计缺陷的一个迹象是希望多次调用静态构造函数,或者在同一对象上多次调用实例构造函数。
确定所需的可重复行为,将其移至单独的方法中,并根据需要从构造函数和其他地方调用它。然后仔细检查你的设计逻辑,因为这是在类设计中发现的一个相当严重的错误,并且表明你有更深层次的问题。
The point of a constructor is to put things into a desired initial valid state.
An instance constructor puts an instance into an initial valid state.
An instance constructor that takes arguments puts an instance into a initial valid state that reflects its arguments.
A static constructor puts the type into an initial valid state. E.g. initialising static members used by the class' static methods or shared by all instances.
Ideally all methods will leave the object and the type in a valid state, but constructors differ in being responsible for getting it into one in the first place.
Any attempt to call a constructor twice is therefore a mistake, since "put it into an initial valid state again" isn't something you can logically do twice ("initial" and "again" don't work well in the same clause). We are helped by the compiler (in it refusing to compile) and the language (in there being no way to express this) from doing such a thing.
And, being a logical impossibility it isn't something you can actually want to do (well, I can want to draw a triangle with more than 3 sides, but only to say that I did). This suggests that you are using your constructor to do something other than setting up an initial valid state.
Doing anything other than establishing such a valid state in a constructor is (as is failing to do so) at best an optimisation, quite often a serious design flaw and quite possibly (worse of all because it goes unfixed longer) an attempted optimisation that is really a serious design flaw.
One sign that your attempt at an optimisation is really a design flaw is a desire to call a static constructor more than once, or to call an instance constructor more than once on the same object.
Identify the desired repeatable behaviour, move it into a separate method, and have it called as needed from both the constructor and elsewhere. Then double check your design's logic, as this is quite a serious mistake to find in a class design and suggests you've got deeper problems.