Omer van Kloeten's .NET Zen

Programming is life, the rest is mere details

News

Omer van Kloeten's Facebook profile

Omer has been professionally developing applications over the past 8 years, both at the IDF’s IT corps and later at the Sela Technology Center, but has had the programming bug ever since he can remember himself.
As a senior developer at NuConomy, a leading web analytics and advertising startup, he leads a wide range of technologies for its flagship products.

Get Firefox


powered by Dapper 

.NET Resources

Articles :: CodeDom

Articles :: nGineer

Culture

Projects

Pitfall: Static Field Inline Initialization Order of Execution

Lean by Katayun, CC-BY-NC-SA Here's something I fell into today. You have a class that has some members that need to be calculated once. So you use static readonly fields. One of those members is a calculation of some of those members. Take the following code for instance:
public class StaticDemo
{
    static readonly int Sum = A + B;
    static readonly int A = Calculator.GetA();
    static readonly int B = Calculator.GetB();
}

This code will initialize A and B from the Calculator class and initialize Sum from the sum of A and B. However, when you run this code, Sum will equal 0, no matter what A or B are.

Why is this? Apparently, when initializing static fields inline, the order of execution is from top to bottom, regardless of dependencies. Trying to use the same method to initialize an instance field will result in the error A field initializer cannot reference the non-static field, method, or property.

So how do we solve this, you ask?

public class StaticDemo
{
    static readonly int A = Calculator.GetA();
    static readonly int B = Calculator.GetB();
static readonly int Sum = A + B;
}
Now Sum will really equal the sum of A and B. Simple, but a sure-fire pitfall if you don't know it.
Posted: Aug 19 2008, 05:09 PM by Omer van Kloeten | with 9 comment(s)
Filed under:

Comments

Doron Yaacoby said:

I think that in this case I would have used a static constructor to initialize all fields. This would make the fact that we are depending on the order more explicit.

# August 20, 2008 12:08 PM

Arjan`s World » LINKBLOG for August 20, 2008 said:

Pingback from  Arjan`s World    » LINKBLOG for August 20, 2008

# August 20, 2008 5:12 PM

Jason Haley said:

# August 20, 2008 10:52 PM

Bill Sorensen said:

I've been bitten by that too. We use a nice free product called Regionerate (www.rauchy.net/regionerate), and it can be configured to sort members in a region alphabetically. These "cosmetic" changes can affect behavior when static fields depend on the order of initialization.

# August 21, 2008 10:50 PM

Patrick De Boeck said:

That's why you should use static constructors !!

# August 22, 2008 3:46 AM

Omer van Kloeten said:

Patrick,

Once you introduce a static constructor, type initialization becomes slower.

# August 22, 2008 8:14 AM

Eyal said:

Another solution for the code above, although sum isn't readonly, but it will cose additional IL instruction so I can live with this :-)

public class StaticDemo

{

   static int Sum {get { return A + B;} }

   static readonly int A = Calculator.GetA();

   static readonly int B = Calculator.GetB();

}

# August 22, 2008 8:24 AM

Omer van Kloeten said:

I don't like that, since albeit inlined, it still costs me more to calculate Sum all over again every time.

# August 22, 2008 11:16 AM

Bart said:

For reference purposes only, sections 10.4.5.1 and 10.4.5.2 of the C# language specification precisely outline this behavior and also why it doesn't work this way for instance members.

-Bart

# August 24, 2008 2:27 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)