Thursday, February 09, 2006

Doh! VB.Net and C# have different order-of-execution for field initializers...

He stared at the code for some time. The field was Nothing, when there was clearly a field initializer present. What the ...?

It turns out that C# and VB.Net differ in the order in which field initializers and constructors fire in an inheritance tree, whereas me being somewhat C# orientated had assumed the C# way was the .Net / CLR way (those kind of assumptions always get you in the end).

So in C# (as you know) all fields are initialized before any instance constructors run, working from most derived to base class, then the constructors fire from the base out:
Out: Initializing static field initializer in BaseClass
Out: Initializing static field initializer in DerivedClass
Out: Initializing field initializer in DerivedClass
Out: Initializing field initializer in BaseClass
Out: Initializing field in constructor in BaseClass
Out: Initializing field in constructor in DerivedClass
However in VB.Net all the base class field initializers and constructors run before the derived class gets a look in:
Out: Initializing shared field initializer in BaseClass
Out: Initializing shared field initializer in DerivedClass
Out: Initializing field initializer in BaseClass
Out: Initializing field in constructor in BaseClass
Out: Initializing field initializer in DerivedClass
Out: Initializing field in constructor in DerivedClass
This is probably due to the slightly looser rules VB has about what can go in a field initializer (eg dates). I'm guessing they probably fudge the IL so all those field initializers end up rolled into the constructor), but aaaaaaaaaarrrggghh... .

(I wonder what happens with cross-language inheritance....)

Of course none of this would be a problem if people[*] avoided the 'calling virtual methods from a constructor' trap, but at least in C# you can use the field initializers to (partly) ameliorate the problem. In VB, no.

ConstructorsShouldNotCallBaseClassVirtualMethods
Brad Abrams : New Design Guideline: Virtual Members

* by people, obviously I mean whomever originally wrote the class I was struggling with

1 comment:

piers7 said...

There's a good discussion on the whys and wherefores of the C# order-of-initialization scheme on Eric Lippert's blog:

Why Do Initializers Run In The Opposite Order As Constructors? Part One

Why Do Initializers Run In The Opposite Order As Constructors? Part Two

...but don't forget that he's only talking about the CLR / C# scheme (the fact it's not used by VB is mentioned in the comments, but not clear in the article text)

Popular Posts