我最近把我正在做的一个项目从.NET 3.5迁移到了.NET 4,我使用的是C#、托管C++和非托管C++。
在我的一个托管C++ (互操作)中,我有一个静态构造函数:
public ref class StaticPool : public BaseStaticPools
{
public:
static StaticPool()
{
InitializePools();
}
static Poolable^ Dequeue()
{
return (Poolable^)Dequeue(Poolable::typeid);
}
private:
static void InitializePools()
{
BaseStaticPools::CreatePool(Poolable::typeid);
}
};在.NET 3.5中,一旦Dequeue()第一次被调用,它就会触发静态初始化,从而运行静态构造函数。一旦我迁移到.NET 4.0,静态构造函数就再也没有被调用过。
我知道.NET 4.0中的静态初始化有一些变化,但根据我所读到的,它应该可以很好地工作。
发布于 2012-01-24 23:04:13
在.NET中,类型初始值设定项只能在第一次访问字段时调用。这由[BeforeFieldInit]属性控制。
我提交了一个bug报告,尽管被标记为“公共”,但它只对beta测试人员可用。
以下是来自Microsoft的解释,您可能会发现这对您有帮助:
对于C++,这是预期的行为。我们用
BeforeFieldInit标记我们的类,因此CLR执行的初始化是正确的。我们不提供在C++/CLI中更改此行为的方法。如果需要运行类构造函数,则可以显式调用System.Runtime.CompilerServices.RuntimeHelpers::RunClassConstructor。
因为我们在这里调用标准,分区I,8.9.5中的代码行是这样的:
如果标记为BeforeFieldInit,则在首次访问为该类型定义的任何静态字段时或之前执行类型的初始值设定项方法。
这一节实际上详细介绍了语言实现如何选择来阻止您所描述的行为。C++/CLI选择不这样做,相反,他们允许程序员这样做,如果他们愿意。
基本上,由于下面的代码绝对没有静态字段,所以不调用静态类constructors.是完全正确的
发布于 2012-04-13 17:16:07
Jon Skeet在这个话题上写道:
https://stackoverflow.com/questions/8989003
复制相似问题