The type initializer threw an exception

In case this error seems to appear out of thin air in your application, this is usually an indication that a variable declared in one of your classes (likely a static class) is having trouble getting or setting it’s value.

You likely may already be frustrated since the reason for this error is not always apparent, but never fear, it is probably your variables fault. πŸ™‚

If you drill down further into this error through the exception stack trace, you can actually see the details where it is breaking, but if you’re looking for a fix without having to step through a lot of code, continue reading.

The usual culprit I find for this error is in older code heavily utilizing many static classes which have class variables used instead of properties (<.<). Since it’s not a property, you can’t set breakpoints within the getter/setter, and setting a breakpoint on the variable itself will not work either.

You are basically left with two different approaches you can take to resolve the problem:

1st Approach:
Set your values for class variables in an initializer method.

This will allow you to see where the exception is actually occurring and also give you greater control over each variable’s initial value (such as conditional logic to control the initial value dynamically) which you might need later on or already be implementing in some other method early in the process flow.

2nd Approach (best IMO):
Change all class variables to properties, go object instance instead of static and add try/catch exception handling in the initializer or getter/setter.

This will also allow you to see where the exception is occurring and still give you the same degree of control over initial value without having the mess of a long initialization function if you would prefer to keep everything in the getter/setter.

Brief Note: In the examples below, a “third approach” would technically work also where the logic causing the failure is simply corrected, however, especially in the case of large conditional blocks, point of failures in future iterations is not always predictable at the time of development. If you’re doubting this, and think your logic is always soundproof, read up on Alan Turing. πŸ˜‰

Example class (this should compile):

static class someappclass1 {
static string appname = "My Cool App";
static string shortappname = shorten(appname);
static string devname = "Ronnie Diaz;"
static string appversion = "1.0.0";
static string lastupdated = "2011/04/28";
static string programfilespath= Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + "\\";
static string apppath = programfilespath + appname; //assuming you installed app first

static void dosomemethod()
{
}

static string shorten(string value) {
int maxlen = 6;
if (value.Length < 6) {maxlen = value.Length;}
value += value.Replace(" ",""); //remove all spaces
return value.SubString(0,maxlen).ToUpper(); //return short DOS compatible name
}
}

Doesn’t look too bad right? Conditional logic checks to make sure substring doesn’t throw an exception if appname is too short. On first run this should compile np.

Now you might be thinking, It is generally never a good idea to initialize any class or static variables using functions, and if you’re thinking this then you are definitely right, but keep in mind just because the function is user defined, it is just as likely you could encounter this issue using a function built in to .Net.

Additionally, in many cases, the “initial state” of a class/obj may be dependent on factors that are not constant and require lookup or calculation (see warehouseproduct class for real world example of such a case).

Can you find the flaw in the code above?

Change appname to a couple different values and in many cases it will work. Lets say your boss takes notice of your app and decides “Cool” is unprofessional and should be removed. NP you say, and with a couple keystrokes, voila! “My Cool App” is now just plain old “My App”. Compile…run.. wait, what happened?

Hint: It’s hiding on line 14.

Since the length of the appname is checked prior to the replacement of the whitespace, the resulting return value is shorter than the upper range of the maxlen variable when substring is calculated. Doh!

But you might be thinking, what kind of bad dev would make this mistake? Well consider this..

In this code example, if it was converted from some ancient VB .Net project which used “Left” instead of “SubString” the issue would not occur, making the problem seem like your conversion skills rather than the previous dev’s poor code structure.

Lesson to learn here: be careful taking shortcuts! If you’re new, it’s OK, this happens.. but if you’re experienced, shame shame!

(If you were using regression testing btw you would catch this problem early, but that is a discussion for another day… πŸ˜‰ )

That was easy…

Wait! Don’t stop reading yet! This is about more than just fixing a bug or exception in .Net that happened out of nowhere, it’s about coding fundamentals :).

So you might be thinking: “That code example was simple, I can fix that NP!.. Move line 14 up one, (between 12 and 13) and voila!”

Well, this would work, but it would form poor programming habits.. Why? Take a look at the alternative example below.

static class warehouseproductname {
static string product_name = "somename";
static string product_internalid = "someguid";

//dimensions as well as other subtypes below could of course be subclassed.. but for purposes of simplicity in this blog kept within same class for user readability in the example
static int product_dimensions_height = "someheight";
static int product_dimensions_width = "somewidth";
static int product_dimensions_squarefootage = product_height*productwidth;
static bool product_dimensions_issquare = (product_height==product_width) ? true:false;
static bool product_dimensions_isrectangular (product_dimensions_issquare==true) ? true:false;

static string vendor_id = lookup_vendor_id(internalid);
static string vendor_name = lookup_vendor_name(vendor_id);

static string warehouse_id = lookup_warehouse_id(internalid,vendorid);
static string warehouse_name = lookup_warehouse_name(warehouse_id);

//etc..
}

A type initializer exception would be much harder to debug in this example… Instead of narrowing it down to 1 of 2 functions, you’re now potentially stepping through to find 1 of 6 functions that could be broken.

See now why this would be a bad habit to make early on? πŸ˜›

Once you get to the above scenario, you should already be planning how you’re going to convince whoever you need that a major recoding needs to take place..

I would avoid discussing the details of OOP with the higher ups, they tend to interpret it as… O.O, but hopefully if you’re still reading you have realized this is what needs to happen here.

The Solution

(finally)

1st approach using first example class:

static class someappclass2 {
static string appname = ""'
static string shortappname = "";
static string devname = "";
static string appversion = "";
static string lastupdated = "";
static string programfilespath= "";
static string apppath = "";

static void dosomemethod()
{
}

static string shorten(string value) {
int maxlen = 6;
if (value.Length < 6) {maxlen = value.Length;}
value += value.Replace(" ",""); //remove all spaces
return value.SubString(0,maxlen).ToUpper(); //return short DOS compatible name
}

static void Load() {
appname = "My Cool App";
shortappname = shorten(appname);
devname = "Ronnie Diaz;"
appversion = "1.0.0";
lastupdated = "2011/04/28";
programfilespath= Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + "\\";
apppath = programfilespath + appname;
}
}

2nd approach using first example class:

class someappclass3
 {
string appname {get;set;}
string shortappname {get;set;}
string devname {get;set;}
string appversion {get;set;}
string lastupdated {get;set;}
string programfilespath {get;set;}
string apppath {get;set;}

void dosomemethod() {
}

string shorten(string value) {
int maxlen = 6;
if (value.Length < 6) {maxlen = value.Length;}
value += value.Replace(" ",""); //remove all spaces
return value.SubString(0,maxlen).ToUpper(); //return short DOS compatible name
}

//ahh initializer, you can even pass in values to override the initials if you'd like
public someappclass() {
try {
appname = "value";
//etc..
}
catch (Exception ex) {
//yell loudly. alternative you could also wrap each get set and/or put this within the get/set of each individual property. don't forget your redbull
}
}

}

In case you clicked on the fundamentals link earlier and wondering how it’s relevant, notice the above class is not static on the inside… that’s because it’s a fig newton! Our previous examples were like a tough paste, yeah the paste could probably hold itself together, but it works much better when it’s wrapped in something stronger!

Comparison of end results on calling code:

public static void Main(string[] args)
{
//example that throws errors
someappclass1.dosomemethod();

//approach 1
someappclass2.Load();
someappclass2.dosomemethod();

//approach 2
someappclass3 appclassobj = new someappclass3();
appclassobj.dosomemethod();

}

So if you still need a singleton in your project and decide you like approach 2, you could always declare a static var as an object of someappclass3 and access this the same way as if the class of the obj itself was static. Such as:

static class Shared {
static someappclass3 appclassobj; //no need to instantiate, just call dosomemethod from main
}

Conclusion

The end result is roughly the same in either approach 1 or 2, although behind the scenes they are very different.

IMO approach 2 is technically “more correct”, especially if you will be doing any multi-threaded development in the application later. However, keep in mind for your particular scenario which is more practical and realistic for your needs.

There are probably other scenarios out there which throw a similar error. If anyone comes across this article encountering something similar but not resolved by the information above, feel free to post additional info. or send me an email to ronnie [at] ronniediaz [dot] [com] and I will help in any way I can.

References
Wikipedia (Alan Turing), http://en.wikipedia.org/wiki/Alan_Turing
Wikipedia (OOP), http://en.wikipedia.org/wiki/Object-oriented_programming
Wikipedia (Singleton), http://en.wikipedia.org/wiki/Singleton_pattern
MSDN (Blogs), http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/8e4532e6-97e7-435d-bbc3-93fef26ff684/

Advertisements

About Ronnie Diaz

Ronnie Diaz is an enterprise software engineer responsible for front-end and back-end development for companies in many industries. Heavily involved in cloud development, online retail, e-commerce and electronic ordering, fulfillment and customer relational systems.

Posted on April 28, 2011, in Programming & Development and tagged , , , , , , , , , , , . Bookmark the permalink. Leave a comment.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: