首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >.net4中未调用托管C++静态构造函数

.net4中未调用托管C++静态构造函数
EN

Stack Overflow用户
提问于 2012-01-24 23:01:14
回答 2查看 1.3K关注 0票数 3

我最近把我正在做的一个项目从.NET 3.5迁移到了.NET 4,我使用的是C#、托管C++和非托管C++。

在我的一个托管C++ (互操作)中,我有一个静态构造函数:

代码语言:javascript
复制
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中的静态初始化有一些变化,但根据我所读到的,它应该可以很好地工作。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 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.是完全正确的

票数 6
EN

Stack Overflow用户

发布于 2012-04-13 17:16:07

Jon Skeet在这个话题上写道:

Type initialization changes in .NET 4.0

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8989003

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档