Disclaimer: This is a personal web page. Contents written here do not represent the position of my employer.
Wednesday, February 04, 2009
My first .NET runtime wishlist item
Heh, I came up with this while coding a patch for Banshee:
Shouldn't this print Hello World instead of just Hello? Basic initializations should have more priority than those involving constructors :)
At least it works if you replace the second static with const... But this confused me a bit for a while. So definitely something the compiler could warn about (ok, Gendarme is another candidate too).
UPDATE: And anyway, if we accept that our runtime is not so clever, it should give a NRE instead of printing Hello, right? You cannot concatenate a string with null. So is this a .NET bug?
UPDATE: Doh! I could have sworn that I got a lot of NRE's in the past when coding this
public class TestStaticInits
{
public static readonly X var = new X ("Hello" + world);
private static string world = " World";
}
public class X
{
public X (string s)
{
Console.WriteLine (s);
}
public override string ToString () { return "Bye"; }
}
public class WishList
{
public static int Main(string[] args)
{
Console.WriteLine (TestStaticInits.var.ToString ());
return 0;
}
}
Shouldn't this print Hello World instead of just Hello? Basic initializations should have more priority than those involving constructors :)
At least it works if you replace the second static with const... But this confused me a bit for a while. So definitely something the compiler could warn about (ok, Gendarme is another candidate too).
UPDATE: And anyway, if we accept that our runtime is not so clever, it should give a NRE instead of printing Hello, right? You cannot concatenate a string with null. So is this a .NET bug?
UPDATE: Doh! I could have sworn that I got a lot of NRE's in the past when coding this
Console.WriteLine ("Hey" + null);
(I mean, when using a var and not protecting against null). Thanks for all the comments.Labels: CSharp, General, Mono, Programacion
Comments:
<< Home
There can be no ordering of initialization of statics that satisfies all scenarios: what if there was a cycle in the dependencies? Not all dependencies can be calculated due to the limits of code analysis, aka the halting problem, since the initializers can call arbitrary static methods.
Static initializers are handled in a predictable fashion, rather than trying to achieve the impossible. They are executed in order, as if they were injected into the start of a class constructor.
Constants are different, because they are baked into their use sites; this means they need to be evaluated by the compiler, which in turn means an ordering can be calculated for them, with a diagnostic on a cycle. This isn't problematic because the initializer for a constant can't be e.g. a constructor call or static method call; the compiler needs to be able to evaluate it at compile time (in order to bake-in uses), so it can easily discover any cycles.
And finally, contrary to what you think, it is perfectly possible to concatenate as many null strings as you like. Try this on for size:
string x = (string) null + (string) null + (string) null;
No errors, no problems, and x is an empty string afterwards.
Finally, don't declare variables called var. It conflicts with the pseudo-keyword "var" :)
Static initializers are handled in a predictable fashion, rather than trying to achieve the impossible. They are executed in order, as if they were injected into the start of a class constructor.
Constants are different, because they are baked into their use sites; this means they need to be evaluated by the compiler, which in turn means an ordering can be calculated for them, with a diagnostic on a cycle. This isn't problematic because the initializer for a constant can't be e.g. a constructor call or static method call; the compiler needs to be able to evaluate it at compile time (in order to bake-in uses), so it can easily discover any cycles.
And finally, contrary to what you think, it is perfectly possible to concatenate as many null strings as you like. Try this on for size:
string x = (string) null + (string) null + (string) null;
No errors, no problems, and x is an empty string afterwards.
Finally, don't declare variables called var. It conflicts with the pseudo-keyword "var" :)
http://www.jaggersoft.com/csharp_standard/17.4.5.htm
"2 Thus, when a class is initialized, all static fields in that class are first initialized to their default values, and then the static field initializers are executed in textual order."
So put the 'world' field first and one sees Hello World. Seems that simple rule is better than anything more complex. :-)
There's also no problem with concatenating a string with null.
http://msdn.microsoft.com/en-us/library/a6d350wd.aspx "An Empty string is used in place of any null argument."
"2 Thus, when a class is initialized, all static fields in that class are first initialized to their default values, and then the static field initializers are executed in textual order."
So put the 'world' field first and one sees Hello World. Seems that simple rule is better than anything more complex. :-)
There's also no problem with concatenating a string with null.
http://msdn.microsoft.com/en-us/library/a6d350wd.aspx "An Empty string is used in place of any null argument."
This way:
public class TestStaticInits
{
private static string world = " World";
public static readonly X var = new X("Hello" + world);
}
works (prints "Hello World")
McHack
Post a Comment
public class TestStaticInits
{
private static string world = " World";
public static readonly X var = new X("Hello" + world);
}
works (prints "Hello World")
McHack
<< Home