2012-01-24 4 views
2

Недавно я перевел проект, над которым я работаю с .NET 3.5 на .NET 4. Я использую C#, управляемый C++ и неуправляемый C++.Управляемый C++ Статический конструктор, не вызываемый .net4

В одном из моего Managed 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, но, согласно всем, что я прочитал, он должен работать нормально.

+0

"Управляемый C++", как и в [управляемых расширений для C++] (http://msdn.microsoft.com/en-us/library/ aa712574 (v = vs.71) .aspx) или [C++/CLI] (http://msdn.microsoft.com/en-us/magazine/cc163852.aspx)? –

+0

Управляемый C++ - это только .NET 1.x, он был заменен C++/CLI. Я исправил ваши теги. –

+0

@Samuel: поскольку код имеет '^' для дескрипторов вместо '__gc *', он не может быть управляемыми расширениями для C++. –

ответ

5

В .NET инициализаторы типа можно вызывать только при первом обращении к полю. Это контролируется атрибутом [BeforeFieldInit].

Я подал отчет об ошибке, который доступен только бета-тестерам, несмотря на то, что он отмечен как «Общественный».

Вот объяснение от Microsoft, которая может оказаться полезной:

Для C++, это предполагаемое поведение. Мы отмечаем наши классы BeforeFieldInit, и поэтому инициализация CLR выполняется правильно. Мы не предлагаем способ в C++/CLI изменить это поведение. Если вам требуется запустить конструктор классов, вы можете явно вызвать System.Runtime.CompilerServices.RuntimeHelpers::RunClassConstructor.


Поскольку мы вызов стандарта здесь, линия из раздела I, 8.9.5 говорит, что это:

Если отмечено BeforeFieldInit то метод инициализатора типа является выполненным в, или раньше, первый доступ к любому статическому полю, определенному для этого типа.

В этом разделе подробно рассказывается о том, как реализация языка может предотвратить предотвращение поведения, которое вы описываете. C++/CLI выбирает не, а они позволяют программисту делать это, если они того пожелают.

В принципе, , поскольку код ниже не имеет абсолютно никаких статических полей, JIT полностью корректен, просто не вызывая статические конструкторы классов.

+0

ссылка, которую вы положили, повреждена. – Aan

+0

Да, я не мог открыть ссылку.Однако я вызываю статический метод, недостаточно ли для запуска статического конструктора? –

+0

@Adban: нет ничего плохого в ссылке, но, видимо, страница проблемы видна только бета-тестерам. –

Смежные вопросы