4

So I have a field in a class, but for some reason it is comming back with an uninitialised value of 0001.01.01.

 private static DateTime start = new DateTime(2011, 1, 1);

There's another static method used as an initializer in another field.

 private static readonly DateTime[] dates = SetupDates(20 * 12);


 private static DateTime[] SetupDates(int n){
    var d = start;
    ....
 }

I thought that "new" in start would need to be completed before before SetupDates could continue... so local variable d would contain 2011.1.1. Looks like I'm mistaken, and I should use a static constructor instead. Is this behaviour to be expected?

3
  • yes it is. ty for picking that up. Commented Jan 26, 2012 at 10:46
  • 1
    Also SetupDates returns void but is setting a field. Commented Jan 26, 2012 at 10:48
  • Just add some breakpoints into those lines. That will clear up the order of execution. Using inheritance could do strange things to the order the code is executed. Commented Jan 26, 2012 at 10:49

5 Answers 5

6

The order matters here.

The static field variable initializers of a class correspond to a sequence of assignments that are executed in the textual order in which they appear in the class declaration.

Make sure your start static field is declared first. Or better yet use a static constructor so you're not relying on the order of fields.

For example this works:

    private static DateTime start = new DateTime(2011, 1, 1);
    private static readonly DateTime[] dates = SetupDates(20 * 12);

But this doesn't

    //Bad SetupDates relies on start which is not initialized
    private static readonly DateTime[] dates = SetupDates(20 * 12); 
    private static DateTime start = new DateTime(2011, 1, 1);

Assuming you change SetupDates to return a DateTime[]

Sign up to request clarification or add additional context in comments.

3 Comments

I moved the order around, and that fixed the problem. Thanks for pointing this out. Is this to be expected in C#? Is it a bug in the C# implementation? Okay... followed that link. That settles it. ty.
@sgtz The link at the top of the answer is to the C# specification where the quote is taken from. So yes it's expected and no it's not a bug. However, it's a bit surprising and anyone refactoring your class may not realise that moving the order has an effect.
agree. I was surprised at least. I'll put things like this into the constructor when order is important.
2

Simply move all Init code to the static constructor and execute it in the Order you want it to execute. Case closed ;)

Comments

1

You cannot call the instance method SetupDates for constructing the static field dates. This code should not compile.

1 Comment

Okay, then ignore this answer and go with CodingBarfield's.
1

No the static fields initialized before you call SetupDates(), there is something other mistaken in your code, which is not visible from the code actually provided.

For example I see the declaration:

private void SetupDates(int n)

but also

private static readonly DateTime[] dates = SetupDates(20 * 12);

EDIT

If SetupDates() intializaes the static field , like in code provided (but I repeat the code is not correct as is), you should keep attention on order of intialization. In that case there could be possible case when the SetupDates() is called before start intialized.

The function doesn't return anything, it couldn't possibly even compile.

2 Comments

But the SetupDates is itself initialising a static field. So what you said can't be true.
@Ray: correct, and I edited the post to make it more clear. But the thing is that the code provied, as is, wouldn't even compile, so it's not absolutely clear what is going on there.
0

Do not understand you question, can you please post only the piece of code causing problems ? The code above doesn't compile. You can initialize a static field with a New object.

     var test = new Test();
     test.SetupDates();

If you put a breakpoint in the SetupDates method the date will be 1/1/2011

  public class Test {
        private static DateTime start = new DateTime(2011, 1, 1);       


        public void SetupDates()
        {
            //breakpoint here
            var d = start;

        }
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.