473,403 Members | 2,284 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,403 software developers and data experts.

TypeInitializationException / forcing all static c'tors to run on startup

I just got a TypeInitializationException exception. Why it is a
common cause for this?

The InnerException is System.FormatException, although I don't see
anything requesting something to be formatted.

I'm trying to invoke the use of a class, to force its static c'tor to
run, which will run its unit test. Is there a good way to force all
class's static c'tors to be run on startup?

Zytan

Mar 1 '07 #1
18 7084
Is there a good way to force all
class's static c'tors to be run on startup?
No simple way. You could perhaps have a dummy static method (NOP, no
in-lining) marked with a known bespoke attribute; use reflection to
scan for this over all classes and invoke? This would (under C# rules;
the CLR actually supports more complex loading strategies) force the
static ctor (if one) to execute... Or create and instance of the class
if default ctors are available... but nothing simple.

Of course, you could simple list the necessary dummy static methods in
the top of Program.cs / global.asax - would be more efficient at
runtime, but higher maintenance.

Marc

Mar 1 '07 #2
Zytan <zy**********@yahoo.comwrote:
I just got a TypeInitializationException exception. Why it is a
common cause for this?

The InnerException is System.FormatException, although I don't see
anything requesting something to be formatted.
I'd have a look at the stack traces carefully - they should show which
class is involved.
I'm trying to invoke the use of a class, to force its static c'tor to
run, which will run its unit test. Is there a good way to force all
class's static c'tors to be run on startup?
Well, you can use Assembly.GetTypes() to get all the types in the
assembly, then use Type.TypeInitializer to get a ConstructorInfo which
you can then Invoke.

However, that will force any type initializers which have already run
to be run again, which could be dangerous depending on what they do!

As a side issue, I'm not sure that making static constructors run unit
tests is a good idea. I personally put them in a separate assembly and
run them with NUnit...

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Mar 1 '07 #3
I just got a TypeInitializationException exception. Why it is a
common cause for this?
The InnerException is System.FormatException, although I don't see
anything requesting something to be formatted.

I'd have a look at the stack traces carefully - they should show which
class is involved.
Looking in the stack trace of InnerException, I found this was the
problem:

string s = SomeMethod(); // can return null or "", or any string.
int x = int.Parse("0"+s);

Where "0"+s should work if s is null or "" or a non-empty string.
Commenting out this code removed the exception. What is wrong witt
that code? It runs fine elsewhere.

Zytan

Mar 1 '07 #4
Is there a good way to force all
class's static c'tors to be run on startup?

No simple way.
Ok, thanks Marc. Your suggestions aren't much different from what I'm
doing now.

Zytan

Mar 1 '07 #5
As a side issue, I'm not sure that making static constructors run unit
tests is a good idea. I personally put them in a separate assembly and
run them with NUnit...
Well, I don't want anything overly complex. NUnit doesn't really even
say what it is (how its implemented). I have to download it to find
out. I'd be nice if it were explained a little better on the
webpage. My projects are small at the moment, so maybe I'll look into
NUnit later when I can justify that time, since I can only assume it
is rather complex if they can't give a quick explanation right away.

Thanks,

Zytan

Mar 1 '07 #6
Zytan <zy**********@yahoo.comwrote:
I just got a TypeInitializationException exception. Why it is a
common cause for this?
The InnerException is System.FormatException, although I don't see
anything requesting something to be formatted.
I'd have a look at the stack traces carefully - they should show which
class is involved.

Looking in the stack trace of InnerException, I found this was the
problem:

string s = SomeMethod(); // can return null or "", or any string.
int x = int.Parse("0"+s);

Where "0"+s should work if s is null or "" or a non-empty string.
Commenting out this code removed the exception. What is wrong witt
that code? It runs fine elsewhere.
Well, if it returns "foo" then you'll be trying to parse "0foo" which
will indeed throw an exception.

This looks like odd code to be running in a static constructor
though...

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Mar 1 '07 #7
Zytan <zy**********@yahoo.comwrote:
As a side issue, I'm not sure that making static constructors run unit
tests is a good idea. I personally put them in a separate assembly and
run them with NUnit...

Well, I don't want anything overly complex. NUnit doesn't really even
say what it is (how its implemented). I have to download it to find
out. I'd be nice if it were explained a little better on the
webpage. My projects are small at the moment, so maybe I'll look into
NUnit later when I can justify that time, since I can only assume it
is rather complex if they can't give a quick explanation right away.
No, NUnit is anything but complex.

I strongly recommend that you download TestDriven.NET
(www.testdriven.net) and give it a try.

It's *definitely* worth doing unit testing properly instead of in an
ad hoc manner where you can't easily run all tests, get all results
etc.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Mar 1 '07 #8
string s = SomeMethod(); // can return null or "", or any string.
int x = int.Parse("0"+s);

Well, if it returns "foo" then you'll be trying to parse "0foo" which
will indeed throw an exception.
Yes, that's true. So I need to catch this. Duh.
This looks like odd code to be running in a static constructor
though...
It's code in a method called by a method, called by a method, etc.,
that the unit testing method calls, which is invoked by the static
c'tor. The unit testing hopefully tests everything the class can do.

What I don't get is: Why, when the static c'tor is invoked, why can't
I step through the code?

NOW I GET IT, this code is being run and it's failing because
int.Parse() is throwing the exception. I thought the code wasn't
being run, and it was a type initialization failure (something that
happens before code is run, which I thought must happen a the start of
any function for all local vars or something). But, it IS a type
initialization failure, the type is the class. And the whole unit
testing and all my code is being run all in one go, without option to
step through, which tricked me into believing it wasn't being run, and
so I had to resort to strange ideas in order to explain what was
happening.

OMG.

Why can't it just report the exception at the int.Parse() line?
Strange.

Haha, what a bug.

Thanks again!

Zytan

Mar 1 '07 #9
What I don't get is: Why, when the static c'tor is invoked, why can't
I step through the code?
This only works if I F9 on the static c'tor itself. It won't step
into it when it is invoked automatically.
Why can't it just report the exception at the int.Parse() line?
If you are stepping through the static c'tor execution, via the method
above, when an exception it thrown that is not handled, the exception
thrown is *still* not reported on the spot. It gets tucked deep away
as the InnerException of the TypeInitializationException for the
static 'ctor. <sigh>

So, yeah, Jon, you are right -- static c'tor are NOT the best place to
run unit tests.

Now. What's a better place other than using NUnit? Like for a really
small project? (no project is too small for unit testing.)

Zytan

Mar 2 '07 #10
Zytan <zy**********@yahoo.comwrote:
Now. What's a better place other than using NUnit? Like for a really
small project? (no project is too small for unit testing.)
Even for a really small project, I'd use NUnit. Others recommend
MbUnit, but I don't know that that's any more suitable for small
projects than NUnit is.

Once you've used NUnit a few times, you'll think nothing of using it,
however small the project. Although I tend to put the tests into a
different project, you don't *have* to, if that's more overhead than
you want.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Mar 2 '07 #11
Even for a really small project, I'd use NUnit. Others recommend
MbUnit, but I don't know that that's any more suitable for small
projects than NUnit is.

Once you've used NUnit a few times, you'll think nothing of using it,
however small the project. Although I tend to put the tests into a
different project, you don't *have* to, if that's more overhead than
you want.
Ok, NUnit it is.

But wait. I consider TWO types of unit testing, something I've
conceived myself:

1. run-time unit testing that test a short sample, quickly, that does
as much as it can without getting in the way, which is removed for
final production. This shows incorrect code immediately on the next
run. It's the fastest unit testing feedback possible.

2. indepth testing, overnight testing, that runs for hours, testing
everything. This has everything that #1 can't have since it takes too
long.

Does NUnit do #1 as well? If not, it's not good enough. I thought I
should ask, since you said you put your unit testing in another
project, implying no run-time unit testing. (by 'run time', I just
mean it is run on every execute, preferably at the START, which is why
I want to run all my static c'tor on load.)

Zytan

Mar 2 '07 #12
Zytan <zy**********@yahoo.comwrote:

<snip>
Does NUnit do #1 as well? If not, it's not good enough. I thought I
should ask, since you said you put your unit testing in another
project, implying no run-time unit testing. (by 'run time', I just
mean it is run on every execute, preferably at the START, which is why
I want to run all my static c'tor on load.)
NUnit is specifically for frequent unit testing. It doesn't happen when
you run your application - it happens when you run your tests. That
should happen (IMO) much more often than you start your application.
Running tests should be pretty much as frequent as building - and you
need to write your unit tests appropriately so they run quickly.

Of course, you may decide to have different categories of unit tests,
some of which will take longer to run - but in general, tests which are
run most often are the most useful ones.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Mar 2 '07 #13
NUnit is specifically for frequent unit testing.

Ok great!
It doesn't happen when
you run your application - it happens when you run your tests. That
should happen (IMO) much more often than you start your application.
Ah, I see. Yes, unless you're like me and your application is the
unit tests. But, if my app wasn't, and the unit tests were in another
project, I can totally see why this test project would be run much
more often. It's the *reason* my app is run so often - for testing.
Running tests should be pretty much as frequent as building - and you
need to write your unit tests appropriately so they run quickly.
As i write code, I test it inside of my app by running it. So, if the
unit test project does the testing, then *that's* the code i'll be
running all the time.
Of course, you may decide to have different categories of unit tests,
some of which will take longer to run - but in general, tests which are
run most often are the most useful ones.
I agree. But, the longer tests have value in specific applications.
Such as stress testing multithreading apps. I've done that to confirm
bugs that should exist during mid-implementation, and confirm (within
reason) that they no longer exist once I've solve the problem.

I suppose this change of pace is what 'test driven development' is all
about? It means I've been doing it for a long time, just not quite on
track.

Zytan

Mar 2 '07 #14
Zytan <zy**********@yahoo.comwrote:
NUnit is specifically for frequent unit testing.

Ok great!
It doesn't happen when
you run your application - it happens when you run your tests. That
should happen (IMO) much more often than you start your application.

Ah, I see. Yes, unless you're like me and your application is the
unit tests. But, if my app wasn't, and the unit tests were in another
project, I can totally see why this test project would be run much
more often. It's the *reason* my app is run so often - for testing.
Right. Whereas I only run my application when I want to see "the big
picture" rather than to make sure the tests run correctly.
Running tests should be pretty much as frequent as building - and you
need to write your unit tests appropriately so they run quickly.

As i write code, I test it inside of my app by running it. So, if the
unit test project does the testing, then *that's* the code i'll be
running all the time.
I don't like the confusion between test code and real code - and in
particular, the fact that you'll have to get rid of the test code to
build the "release" version means that your tests won't be running
against the real code.

For instance, having a static constructor in a class subtly changes the
semantics of the class - see
http://pobox.com/~skeet/csharp/beforefieldinit.html
So if you only have a static constructor in a class for test purposes,
you'll be changing the semantics of that class when you remove that
static constructor.
Of course, you may decide to have different categories of unit tests,
some of which will take longer to run - but in general, tests which are
run most often are the most useful ones.

I agree. But, the longer tests have value in specific applications.
Such as stress testing multithreading apps. I've done that to confirm
bugs that should exist during mid-implementation, and confirm (within
reason) that they no longer exist once I've solve the problem.
Yes, that's fine - but they're not unit tests. It's often useful to use
a unit test framework to build/run such tests, but they're not unit
tests.
I suppose this change of pace is what 'test driven development' is all
about? It means I've been doing it for a long time, just not quite on
track.
Test driven development means more than just writing unit tests for
code. It means writing the tests before the code exists in the first
place. The effect of that is that you write code which is always
testable, and your interfaces tend to be usable, because they're driven
by what the caller wants to do, rather than what the class wants to
expose.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Mar 2 '07 #15
As i write code, I test it inside of my app by running it. So, if the
unit test project does the testing, then *that's* the code i'll be
running all the time.

I don't like the confusion between test code and real code - and in
particular, the fact that you'll have to get rid of the test code to
build the "release" version means that your tests won't be running
against the real code.
I don't follow what you mean here.

I run my unit test in debug and release, but in the final-release,
those calls become blank functions (only for speed purposes, if I
could run them, and report errors back home, I'd be happy to do this,
if it didn't have any side effects of slowing the app).
For instance, having a static constructor in a class subtly changes the
semantics of the class - seehttp://pobox.com/~skeet/csharp/beforefieldinit.html
So if you only have a static constructor in a class for test purposes,
you'll be changing the semantics of that class when you remove that
static constructor.
I would just leave the static c'tor, and make the unit test function
call a blank function (or remove the call). The static c'tor has no
unit test code in it, other than the call to the unit test function.
I agree. But, the longer tests have value in specific applications.
Such as stress testing multithreading apps. I've done that to confirm
bugs that should exist during mid-implementation, and confirm (within
reason) that they no longer exist once I've solve the problem.

Yes, that's fine - but they're not unit tests. It's often useful to use
a unit test framework to build/run such tests, but they're not unit
tests.
Hmm? But, they have pretty much the same code. Only the quick unit
test differs in cases where I cannot make a quick version of the
longer unit test. The longer unit test has everything the quick one
has, and more. It has the same function calls, but it calls them
more. I fail to see how they aren't exactly the same thing -- unit
tests. They test my units. One does a more thorough job. I wish it
could do it every compile, but my computer is just not fast enough.
So, the quick test is more unlike a unit test than the long test, if
either, since it doesn't do the full job.

Are you saying there's a strict definition of what 'unit test' means?
Test driven development means more than just writing unit tests for
code. It means writing the tests before the code exists in the first
place. The effect of that is that you write code which is always
testable, and your interfaces tend to be usable, because they're driven
by what the caller wants to do, rather than what the class wants to
expose.
Yes, actually, I knew that. I had read up on it a bit. It's like
coding backwards, a bit. And I haven't been doing that at all.

Zytan

Mar 2 '07 #16
Zytan <zy**********@yahoo.comwrote:
As i write code, I test it inside of my app by running it. So, if the
unit test project does the testing, then *that's* the code i'll be
running all the time.
I don't like the confusion between test code and real code - and in
particular, the fact that you'll have to get rid of the test code to
build the "release" version means that your tests won't be running
against the real code.

I don't follow what you mean here.

I run my unit test in debug and release, but in the final-release,
those calls become blank functions (only for speed purposes, if I
could run them, and report errors back home, I'd be happy to do this,
if it didn't have any side effects of slowing the app).
It still means that the code is different at test time to normal
release.
For instance, having a static constructor in a class subtly changes the
semantics of the class - seehttp://pobox.com/~skeet/csharp/beforefieldinit.html
So if you only have a static constructor in a class for test purposes,
you'll be changing the semantics of that class when you remove that
static constructor.

I would just leave the static c'tor, and make the unit test function
call a blank function (or remove the call). The static c'tor has no
unit test code in it, other than the call to the unit test function.
Then you're getting a (slight) performance penalty for having a static
constructor in every class. It means the JIT can't perform some
optimisations when accessing static members of the class.
I agree. But, the longer tests have value in specific applications.
Such as stress testing multithreading apps. I've done that to confirm
bugs that should exist during mid-implementation, and confirm (within
reason) that they no longer exist once I've solve the problem.
Yes, that's fine - but they're not unit tests. It's often useful to use
a unit test framework to build/run such tests, but they're not unit
tests.

Hmm? But, they have pretty much the same code. Only the quick unit
test differs in cases where I cannot make a quick version of the
longer unit test. The longer unit test has everything the quick one
has, and more. It has the same function calls, but it calls them
more. I fail to see how they aren't exactly the same thing -- unit
tests. They test my units. One does a more thorough job. I wish it
could do it every compile, but my computer is just not fast enough.
So, the quick test is more unlike a unit test than the long test, if
either, since it doesn't do the full job.

Are you saying there's a strict definition of what 'unit test' means?
If it's just testing a single unit, that's fine - sorry, your previous
description of "stress testing multithreading apps" suggested that it
was testing the whole application, rather than a single class.
Test driven development means more than just writing unit tests for
code. It means writing the tests before the code exists in the first
place. The effect of that is that you write code which is always
testable, and your interfaces tend to be usable, because they're driven
by what the caller wants to do, rather than what the class wants to
expose.

Yes, actually, I knew that. I had read up on it a bit. It's like
coding backwards, a bit. And I haven't been doing that at all.
It takes a while to get used to, and it's not *always* suitable, but it
can produce fabulous results.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Mar 3 '07 #17
I run my unit test in debug and release, but in the final-release,
those calls become blank functions (only for speed purposes, if I
could run them, and report errors back home, I'd be happy to do this,
if it didn't have any side effects of slowing the app).

It still means that the code is different at test time to normal
release.
Very true. While it shouldn't matter, I have seen bugs where
independent pieces of code have dependencies, and it could just be
where the first static c'tor is run. But, hopefully, the unit testing
should solve those exact problems before they could become a problem.

I thought maybe the unit test could be left in, as an even faster
version of the normal one that is run on every execute. Something
that takes 1/100th of a second, or 1/10th of a second maximum. And it
could report to home base if there's an error, and continue on. I've
never liked that debug code disappears at release time, and there's
release specific code that will handle as many errors as it can, since
it's too late to call Debug.Assert when it's on the customer's
machine. It'd be nice if something, anything, could be done, at least
during the first 0.1 seconds of launch to test a few things, and
report home about possible issues. This is something I highly doubt
anyone does.
I would just leave the static c'tor, and make the unit test function
call a blank function (or remove the call). The static c'tor has no
unit test code in it, other than the call to the unit test function.

Then you're getting a (slight) performance penalty for having a static
constructor in every class. It means the JIT can't perform some
optimisations when accessing static members of the class.
Oh, ok.

Zytan

Mar 5 '07 #18
Zytan wrote:
>>I run my unit test in debug and release, but in the final-release,
those calls become blank functions (only for speed purposes, if I
could run them, and report errors back home, I'd be happy to do this,
if it didn't have any side effects of slowing the app).
It still means that the code is different at test time to normal
release.

Very true. While it shouldn't matter, I have seen bugs where
independent pieces of code have dependencies, and it could just be
where the first static c'tor is run.
C# should not have much of the classic C/C++ unpredictable
behavior for various memory related bugs.

But there are a fundamental problem proving that the
the unit test code itself is the only difference between
what you tested and what you put in production.

Arne
Mar 6 '07 #19

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Tim | last post by:
Please advise if you can. Presumably initialisation of members in member initialisation lists is perfomed by 'C' run-time startup. If the CRT was never started-up would those members be garbage?...
8
by: Simone Chiaretta | last post by:
I've a very strange behaveour related to a website we built: from times to times, something should happen on the server, and all static variables inside the web application, both defined inside aspx...
10
by: appdevtech | last post by:
A little background… We have multiple web servers in a farm and are starting to upgrade some applications to 1.1 by re-compiling in VS2003. One of the things out of our direct control is the...
7
by: James Crosswell | last post by:
I want to create a class with a static property as follows: class MyClass { private static List<MyHandlerRegisteredHandlers = new List<MyHandler>; } I then want to be able to create...
5
by: Parapura Rajkumar | last post by:
hey all class A { }; class B {
3
by: John Shell | last post by:
Hello, all. The following code results in a C2666 error (2 overloads have similar conversions). class FSVec2D { public: FSVec2D() { // code omitted }
55
by: Zytan | last post by:
I see that static is more restricted in C# than in C++. It appears usable only on classes and methods, and data members, but cannot be created within a method itself. Surely this is possible in...
6
by: Grey Alien | last post by:
class A { public: A(const B& ref); private: static B& b ; }; How may b be initialized ?
3
by: greek_bill | last post by:
Hi, I quite often need to have a system of classes providing alternative implementions of some concept and need each class to register itself with a manger (singleton) class. A good example...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.