C# 托管C++;在.net4中未调用静态构造函数
我最近将一个正在进行的项目从.NET3.5迁移到.NET4。我使用C++,管理C++和非托管C++。C# 托管C++;在.net4中未调用静态构造函数,c#,.net,c++-cli,C#,.net,C++ Cli,我最近将一个正在进行的项目从.NET3.5迁移到.NET4。我使用C++,管理C++和非托管C++。 在我的一个管理C++(互操作)中,我有一个静态构造函数: public ref class StaticPool : public BaseStaticPools { public: static StaticPool() { InitializePools(); } static Poolable^
在我的一个管理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()
,它将触发静态初始化,该初始化将运行静态构造函数。一旦我转到.NET4.0,就再也没有调用过静态构造函数
我知道.NET 4.0中的静态初始化发生了变化,但据我所知,它应该可以正常工作。在.NET中,只能在第一次访问字段时调用类型初始化器。这由
[BeforeFieldInit]
属性控制
我提交了一份bug报告,尽管标记为“Public”,但该报告仅对beta测试人员可用
以下是Microsoft的解释,您可能会发现这一解释很有帮助:
对于C++,这是预期的行为。我们用BeforeFieldInit标记类,因此CLR执行的初始化是正确的。我们没有在C++/CLI中提供改变这种行为的方法。如果需要运行类构造函数,则可以显式调用System.Runtime.CompilerServices.RuntimeHelpers::RunClassConstructor
由于我们在这里调用标准,分区I中的第8.9.5行表示: 如果标记为BeforeFieldInit,则在首次访问为该类型定义的任何静态字段时执行该类型的初始化器方法 这一部分实际上详细介绍了语言实现如何选择阻止您所描述的行为。C++/CLI选择不这样做,而是允许程序员根据自己的意愿这样做 基本上,因为下面的代码完全没有静态字段,所以JIT完全正确,只是不调用静态类构造函数
Jon Skeet就这个话题写道:
< /P>“管理C++”和.C++中的“.c++”一样,只是.NET 1 .x,它被C++ +CLI所取代。我修复了你的标签。@塞缪尔:因为代码中有代码< > > 句柄,而不是<代码>·yg**/COD>,它不能被C++管理扩展。@ Beoviigt好点-我没有注意到。我也不知道管理C++是.NET 1。x。谢谢大家清理它,我是新的这个地区,所以我想我需要更多的阅读。你把链接损坏。是的,我不能打开链接。但是,我调用的是静态方法,这不足以触发静态构造函数吗?@Adban:链接没有问题,但问题页面显然只对beta测试人员可见。@Lior:因为您无法访问问题页面,所以我将重要的解释复制到这里。基本上答案是“不,调用静态方法是不够的”。Ben Voigt:非常感谢您的努力。然而,我确实尝试访问一个静态字段,但它仍然没有调用静态构造函数。此外,奇怪的是,它在.NET3.5中运行良好,当我在调试模式下运行.NETV4.0时。