4

Following the Type-Safe Enum Pattern, I created a small type-safe enum class. When the main dialog is first invoked, after it calls InitializeComponent, it invokes the constructor of another class, which tries to set one of its class variables to one of the static instances of the type-safe enum class. The issue is that all of these instances (and the class it seems) are null, thus causing the program to crash.

How do I get the program to construct that class and all of its instances first? I'm somewhat confused because I thought that static instances were created at the start of the program, so why does it not do it in this case?

Here's the condensed version of the code that's failing me: The type-safe enum pattern implementation:

public sealed class Types
{
   public static readonly Types INVALID = new Types(-1, "Invalid");
   ... (other static instances and other implementations of the type-safe enum pattern)
}

The initialization of the main dialog:

public dlgMain()
{
   InitializeComponent();
   m_OtherClass = new OtherClass();
   ...
}

The constructor for OtherClass

public OtherClass()
{
   m_eType = Types.INVALID; // Crash!! the entire type-safe enum class and its static members are null!
   ...
}

EDIT: Ok, here was the problem,

public sealed class Types
{
   public static readonly Types INVALID = new Types(-1, "Invalid");
   ... (other static instances)
   private static Dictionary<string, Types> mappings = new Dictionary<string, Types>(6); // There are 6 static types
   private Types(int val, string name)
   {
      m_value = value; m_name = name;
      mappings[name] = this; // This was causing the error, mappings is null
   }
}
Community
  • 1
  • 1
riqitang
  • 3,241
  • 4
  • 37
  • 47
  • 4
    You've condensed the code too much, and not explained how it crashed. Please provide a short but *complete* program (ideally a console app) demonstrating the problem. – Jon Skeet Mar 28 '13 at 15:09
  • alterntely, post the execption at crash – Dhawalk Mar 28 '13 at 15:10
  • A static class can't be `null` hence a crash at the line you marked is *impossible*. Please show your real code. – Daniel Hilgarth Mar 28 '13 at 15:11
  • 1
    @DanielHilgarth No -it's possible. It's most likely due to an issue in the construction of `Types`, which is used to initialize the static data... – Reed Copsey Mar 28 '13 at 15:12
  • EDIT: good call Reed^^ I should've looked at the error message closer, here it is (and I think I can solve it): The type initializer for 'Types' threw an exception. – riqitang Mar 28 '13 at 15:12
  • @ReedCopsey: Ah, indeed. That could be a reason for a crash at this line... – Daniel Hilgarth Mar 28 '13 at 15:12
  • @Sean Yeah - I suspect the problem is your constructor probably expects the static data to be initialized already, which (obviously) won't work... That's the most common culprit. – Reed Copsey Mar 28 '13 at 15:13
  • silly, I should've looked at the constructor of the type-safe enum closer, it's trying to add to a null dictionary (which is also a static member, but not initialized for some reason) – riqitang Mar 28 '13 at 15:14
  • 2
    @Sean If you move all of your initialization into a static constructor, you can control the order and make this work more cleanly. – Reed Copsey Mar 28 '13 at 15:22

2 Answers2

7

How do I get the program to construct that class and all of its instances first? I'm somewhat confused because I thought that static instances were created at the start of the program,

This is actually not true. Static data is created at some point prior to the first use of the type containing the static data. This is often initialized just prior to "using" the values, but not at program startup. (It shouldn't matter in this case, though.)

so why does it not do it in this case?

It actually likely is doing this properly. The problem is more likely within your constructor for Types. When the static constructor runs, it needs to initialize each readonly instance of Types. If the constructor expects the static data to already be initialized or some other similar issue, this can cause an exception to be thrown.

I recommend putting a breakpoint within your Types constructor (and any other constructors being used to initialize your static data). This will typically help diagnose and discover the real problem.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
1

What you are looking for is: Static Constructors.

A static constructor is used to initialize any static data, or to perform a particular action that needs performed once only. It is called automatically before the first instance is created or any static members are referenced.

  • He is talking about static readonly. there is no need for static constructor in static readonly – Dhawalk Mar 28 '13 at 15:07
  • it's a novel idea, but I need to set the class variables in the type-safe enum class, which I can't do with a static constructor – riqitang Mar 28 '13 at 15:10