views:

482

answers:

5

banging my head on this one. I have a static method with fields in a class similar to this:

public MyClass
{
   private static string m_myString;

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

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

}

In Debug mode, I have no issue but as soon as I go to release I get TypeInitializationExceptions. Help appreciated and crow eaten with delight.

A: 

Shouldn't you say:

private static string m_myString = "hello world";
jeffamaphone
A: 

This is often due to the order in which the the static constructor runs.

BTW: I don't think a public static constructor for a non-static class is a good idea, try making it private.

Mitch Wheat
A: 

@jeffamaphone.. yes typo in my code sample.

@Mitch Wheat: yeah that's what it looks like, and my bad you can't add an access modifier to a static constructor.

Anyhow I have it working now, looks more like this, apologies for the mess in the sample code.

public MyClass
{
   private static Object m_object;

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

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

}

and now life is good again. Though I'd be happier if I understood why.

thanks for the replies.

No problem; feel free to upvote our responses! ;)
Mitch Wheat
A: 

One of the problems with statics is that you have no control over when they are instantiated as your program is loaded. In DEBUG mode, the compiler does many things differently than it does in RELEASE mode. One of those things is how it manages memory.

It is quite likely that you are simply getting lucky in DEBUG that your memory is not being overwritten by other processes and the value is there when your program wants it.

One approach I've used to great effect is a variation of the Meyers Singleton. (This is very nicely detailed in C++ In Theory: The Singleton Pattern - J. Nakamura

While you are not after a singleton, the approach can be used to solve your problem as follows:

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

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

The primary benefit is very nicely explained by Mr. Nakamura in the above article:

This construction relies on the fact that function-static objects are only initialized when the function is first being called upon; thus we maintain the benefit of dynamic initialization. (Function-static primitive variables like static int number=100; do get translated during compile time however!)

AJ S.
See: http://msdn.microsoft.com/en-us/library/k9x6w0hc(VS.80).aspx
strager
That's all very interesting, but C# is not C++.
Jim Mischel
You are of course correct.
AJ S.
A: 

Does the TypeInitializationException occur in MyClass, or in some other class? Do you get a stack trace when the exception is thrown?

The little code you've shown doesn't indicate an error, but we can't see the Bar class, or other possibly pertinent code.

Jim Mischel