Статические методы хороши в отладке, но выдают исключение TypeInitializationException в выпуске - PullRequest
1 голос
/ 20 марта 2009

Ударяюсь головой об этом. У меня есть статический метод с полями в классе, похожем на это:

public MyClass
{
   private static string m_myString;

   public static MyClass()
   {
       m_myString = "hello world";
   }

   public static void MyUsefulMethod(Foo bar)
   {
       DoStuffTo(bar);
   }

}

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

Ответы [ 5 ]

0 голосов
/ 20 марта 2009

Встречается ли TypeInitializationException в MyClass или в каком-либо другом классе? Получаете ли вы трассировку стека при возникновении исключения?

Небольшой код, который вы показали, не указывает на ошибку, но мы не видим класс Bar или другой, возможно, соответствующий код.

0 голосов
/ 20 марта 2009

Одна из проблем со статикой заключается в том, что вы не можете контролировать, когда они создаются при загрузке вашей программы. В режиме DEBUG компилятор делает много вещей иначе, чем в режиме RELEASE. Одна из тех вещей - это то, как она управляет памятью.

Вполне вероятно, что вам просто повезло в DEBUG, что ваша память не перезаписывается другими процессами, и значение есть, когда ваша программа этого хочет.

Один из подходов, который я использовал для достижения большого эффекта, - это вариант синглтона Meyers. (Это очень хорошо детализировано в C ++ В Теории: Шаблон Синглтона - Дж. Накамура

Несмотря на то, что вам не нужен синглтон, подход можно использовать для решения вашей проблемы следующим образом:

class MySample
{
    MySample() {}
    <etc.>

    static const std::string& GetStaticValue() 
    {
        static std::string my_val = "Hello World";
        return my_val;
    }
}

Основная выгода очень хорошо объяснена г-ном Накамурой в вышеприведенной статье:

Эта конструкция опирается на тот факт, что функционально-статические объекты инициализируются только при первом вызове функции; таким образом, мы поддерживаем преимущество динамической инициализации. (Функционально-статические примитивные переменные, такие как static int number = 100; однако переводятся во время компиляции!)

0 голосов
/ 20 марта 2009

Это часто связано с порядком, в котором работает статический конструктор.

Кстати: я не думаю, что открытый статический конструктор для нестатического класса - это хорошая идея, попробуйте сделать его закрытым.

0 голосов
/ 20 марта 2009

@ jeffamaphone .. да опечатка в моем примере кода.

@ Митч Уит: да, вот как это выглядит, и, к сожалению, вы не можете добавить модификатор доступа к статическому конструктору.

Как бы то ни было, теперь он работает, выглядит примерно так, извиняюсь за беспорядок в примере кода.

public MyClass
{
   private static Object m_object;

   static MyClass()
   {
      m_object = new Object();
   }  

   public static void MyUsefulMethod(Foo bar)
  {
      DoStuffTo(bar);
   }

}

и теперь жизнь снова хороша. Хотя я бы был счастлив, если бы понял, почему.

спасибо за ответы.

0 голосов
/ 20 марта 2009

Разве вы не должны сказать:

private static string m_myString = "hello world";
...