This code has the well defined behavior in C# of not working:
class Foo
{
static List<int> to = new List<int>( from ); // from is still null
static IEnumerable<int> from = Something();
}
Note: I'm not asking how to fix that code as I already known how to do that
What is the justification for this? C# already does run time checks to detect the first access to static members. Why not extend this to a per member thing and have them run on demand or even better have the compiler figure out the order at compile time?
BTW: I think the same question (or almost the same) also holds for non static members.
Initializers are just a syntactic sugar. Compiler puts that code in the .cctor when it compiles your class, and it pust them in the orders they're layed out in the code.
It doesn't run any checks, because it wouldn't make sense. You could still have initialization cycles, so it wouldn't work anyway.
I blogged about it some time ago if you're interested:
I can envision a programmer depending on initialization order due to side effects with other static classes. You and I both know that depending on side effects is bad practice, but it's not necessarily illegal.
Consider something like this:
class Foo
{
static string header = Bar.GetHeader();
static string version = Bar.GetVersion();
}
And Bar.GetVersion
assumes that Bar.GetHeader
has been called. If the compiler were free to change the initialization order, then the programmer wouldn't be able to guarantee the initialization order.
Ugly, granted, but perfectly legal. If you imagine second-order effects (i.e. called static methods that themselves depend on classes that have side effects), you see that it's impossible for the compiler to reliably rearrange anything, just as it's impossible (in general) for the compiler to rearrange the order of function calls in your static constructor.
C# does runtime checks to detect the first access to a class, but does not re-order static initialization within a class.
The static fields are initialized from top to bottom followed by the static constructors from top to bottom. Either change the order of your fields or create a static constructor and initialize the fields from tehre.
See Variable initializers in the C# spec or this article on initializers.. Also, the question Order of static constructors/initializers in C# is related.
I think what you need to use is a static constructor.
Like so
class Foo
{
static List<int> to;
static IEnumerable<int> from;
static Foo()
{
from = Something();
to = new List<int>(from);
}
}
As to why C# doesn't do it on first access, I just don't see the need for that kind of complexity when there are other alternatives that make it clear what's happening.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With