Static field initialization order with partial classes - c#

Is there any way to force the static field initialization order in partial classes? Let's say in HelloWorld1.cs I have:
partial class HelloWorld
{
static readonly string[] a = new[] { "Hello World" };
}
Elsewhere in HelloWorld2.cs I have:
partial class HelloWorld
{
static readonly string b = a[0];
}
If a is initialized before b this is fine but if b is initialized before a then it throws an. The healthy way is probably to use a static constructor but I'm curious if there's a way to force or predict the initialization order when the fields classes are in different files of the same partial class.

When the fields are present in the same file, the textual order defines the execution of their initialization:
10.5.5.1 Variable initializers - Static field initialization
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. If a static constructor (§10.12) exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor. Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class.
However, in the case of fields declared in different files of partial classes, the order is undefined:
10.2.6 Partial types - Members
The ordering of members within a type is rarely significant to C# code, but may be significant when interfacing with other languages and environments. In these cases, the ordering of members within a type declared in multiple parts is undefined.
From the C# language specification.

From MSDN Documentation:
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. If a static constructor
(Section 10.11) exists in the class, execution of the static field
initializers occurs immediately prior to executing that static
constructor. Otherwise, the static field initializers are executed at
an implementation-dependent time prior to the first use of a static
field of that class.

Related

Static member initialization order within a single C# class

Consider the following class snippet with two static member variables:
public static class Foo
{
static string A = GetA(B);
static string B = "required for A";
...
Now, my understanding is that A and B will be initialized when they are accessed for the first time. However, when I executed a fully-realized version of the snippet above where A was accessed before B was initialized, it led to null being passed in to GetA() instead of "required for A". Why isn't the behaviour to start initializing A, then, when it's realized that B is required to initialize A, initialize B, then return to finish the initialization of A?
What are the general rules around this? Why does it behave this way? I've seen other questions that touch on this (When do static variables get initialized in C#?) but they don't answer this question exactly. What is the static variable initialization order in C#? talks primarily about how this works across classes, not within a single class (though Jon Skeet's addendum to his answer -- "By popular demand, here was my original answer when I thought the question was about the initialization order of static variables within a class:...." does answer this question, it's buried in a much longer answer).
In short, don't do this.
Standard ECMA-334 C# Language Specification
15.5.6.2 Static field initialization
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 (§15.5.6.1). Within a
partial class, the meaning of "textual order" is specified by
§15.5.6.1. If a static constructor (§15.12) exists in the class,
execution of the static field initializers occurs immediately prior to
executing that static constructor. Otherwise, the static field
initializers are executed at an implementation-dependent time prior to
the first use of a static field of that class
The fix is to :
Put them in the order and use Static Constructor,
or just Initialise them in a Static Constructor in turn giving you the ability to control the order of initialisation (given the above information).
Personally i suggest to Initialise them in a Static Constructor, it seems to make it more concrete and understandable, and less likely to be bumped in refactoring

C# Static Order, Member Variables, Member Enums

Four quick questions on static variables that the MSDN Faq and other basic guides seem to neglect.
Is public static the same as static public?e.g. public static class Globals
{...}vs.static public class Globals
{...}Same? Different?
It seems that -- like functions -- variables in a public static class in C# require public static status to be seen inside other classes via the static class's named global instance. Why is this? This seems non-intuitive from a naive perspective (it would seem public static class would provide a singular public instance of the class, with any public variables within available). Clearly this is not the case, so I wanted some perspective from C# experts as to why you have to make your member variables in your static class objects static to provide access. (Note: The MSDN Faq contains an example of a non-static class with static member vars, but nary a discussion on what if any differences having static members with a public static class has.) (i.e. What if any consequences are there of the doubly static status?)e.g. public static class Globals
{ public static Camera camera1; }//doubly static
Is there ever a case where public non-static functions within a public static class are appropriate? I can see that you wouldn't want to expose some things, but wouldn't you just want to make them private in such a case. (The simpler the example, the better, I'm self-taught in C# and still trying to understand more complex topics like reflection, etc.)
Curiously public enum inside a public static class are visible without a static keyword via the named global instance. Why is the typical static requirement not enforced here? Is there anything I should worry about if I use the visible public enum rather than a public static enum?public static class Globals
{ public enum Dummy { Everything=42}; } //Enum is visible w/out static!
Thanks in advance. And apologies for the multiple questions, I was on the fence about whether to split this into multiple posts, but it's all related to C# static use, so I figured one post was most appropriate.
1: Order doesn't matter. There are standards of how to order things, for more readability, but as the compiler reads it all - it doesn't matter at all.
I personally thing that it would be best writing it as "public static", instead of "static public".
If you download ReSharper to your Visual Studio, it has predefined prioritizing to modifiers such as "static", "public", "readonly", etc... And will suggest you, when you are not following those standards, to correct the order of the modifiers. If you choose to work with a different prioritizing of the modifiers, you can change the ReSharper's settings to suit your preferred order.
Other than that - ReSharper does many other wonders and it highly recommended.
2: Static classes can only contain static members. "static" in the class means that the class can have no instances, and is declared as a being, sort of, as you said. "static" for members means a different thing: Normally, a member would be owned by the instance. Static members, however, are owned by the class - shared among all instances of the class and are used without an actual instance of the class.
public static class Math
{
public static readonly int ZERO = 0;
}
Here, you can see that ZERO is static, which means it belongs to the class Math.
So you could do:
Math.ZERO
Even if the Math class wasn't static, you would still access the ZERO member via the class itself. The ZERO will not be a member of a Math instance, because it belongs to the class, and not to an instance - hence "static member".
3: Number2 sort of answers this one as well. Non-Static class would mean that it can have instances of it and members that belong the instances, but you could also have class-members (static) that would belong to the class itself.
Example:
public class Quiz
{
public static readonly int FAIL_GRADE = 45;
public int Grade;
public string StudentName;
}
So every Quiz has a grade and a student associated with it, but there is also a constant which belongs to the whole class "Quiz" which indicates what grade is considered as Fail Grade.
In the case above, you could also simply do:
public const int FAIL_GRADE = 45;
So you can learn that "const" means "static readonly", logically speaking.
But in other cases, when you can't use "const" - you would have to use "static readonly".
The "const" can only come before basic types, such as "int", "float", "bool", etc...
Here is an example where the "static" member is not readonly:
public static class Student
{
public static int TestsTaken = 0;
public string Name;
public int DoQuiz(Quiz quiz, Answers answers)
{
TestsTaken++;
// Some answers checking logic and grade returning
}
}
In the above example, you can see that the static member of the class Student is used as a counter to how many times instances of Student performed a certain action (DoQuiz). The use of it here is actually not really good programming, since TestsTaken is really something that should be in Quiz, or in School class. But the example for "static" usage stands.
4: Enums in static classes don't require the "static" keyword, and in fact you can't declare a static Enum anywhere. Enum is not considered a member of a class, but a sub-type of it (could be sub-class, interface, enum, etc).
The fact that an Enum is declared within a class, simply means that if one wishes to use the Enum, he must reference the class as well. It would usually be places within a class for logic purposes, abstraction or encapsulation (would declare it "private" in this case - so it can be used within the class, but not outside of it).
Example:
public static class Math
{
private enum SpecialSigns
{
Sigma,
Alpha,
Pi,
etc
}
}
In the above example, the SpecialSigns enum can be used from within the Math class, but is not visible to the outside.
You could also declare it public, so when one uses Math class, he could also use the SpecialSigns enum. In that case, you could also have SpecialSigns values as return types of methods, or types of public members. You can't do that when the SpecialSigns is private because the outside code does not have access to it - does not know of it's existence - and therefore cannot understand it as a return value, member type, etc.
Still, the SpecialSigns enum is not a member of the class, but only defined within the scope of it's recognition.
According to Method Specification:
A method-declaration may include a set of attributes (Section 17) and a valid combination of the four access modifiers (Section 10.2.3), the new (Section 10.2.2), static (Section 10.5.2), virtual (Section 10.5.3), override (Section 10.5.4), sealed (Section 10.5.5), abstract (Section 10.5.6), and extern (Section 10.5.7) modifiers.
Sequence doesn't matter
Yes, the order doesn't really matter.
Yes, a static class can only contain static members (with exception of #4), but they don't have to be public.
Yes, you can have public static methods, but private static methods that your public static methods use
Nested type declarations are not required to be static.
Another thing to remember is the "internal" visibility in c#. In my code bases I have found many uses for internal static classes (most of the time for extension methods).

C#: static object variable in class

If I have a static variable in a class:
public class MyClass {
private static MyObject = new MyObject();
public void MyMethod() {
// do some stuff
}
}
Can the variable be instantiated when it is declared, as in the above?
Your code is legal and works.
One thing to be aware of is that static constructors and initalizers don't run when your module is loaded, but only when needed.
MyObject will only be instantiated when you either create an instance of MyClass or access a static field of it.
10.5.5.1 Static field initialization
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. If a static constructor (§10.12) exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor. Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class.
The static constructor for a closed class type executes at most once in a given application domain. The execution of a static constructor is triggered by the first of the following events to occur within an application domain:
· An instance of the class type is created.
· Any of the static members of the class type are referenced.
So as I understand it:
If there is no static constructor the calling of a static method may trigger the initializers but isn't required to do so if the static method uses no static field.
If there is a static constructor it must run when a static member is referenced, so calling of a static method triggers first the static field initializers and then the the static constructor.
Yes. Two particular things to note:
The static variables will be initialized in the order they appear in the class.
They are guaranteed to be initialized before any static constructor is called.
Section 10.5.5.1 of the C# spec goes into more detail in you are interested.
If you are asking if this is legal C#, then yes it is. And it will do what you think it will.

private constructor gets empty private static readonly string

I have the following code. Is it not the exact code which I am using since it is internal to my place of work, but is a representation of the scenario which I am encountering.
public class Service : ServiceBase
{
private static readonly Service _instance = new Service();
private static readonly string a = #"D:\test.txt";
private Service () : base()
{
// the value stored in "a" is always blank.
Console.Writeline(a);
}
static void Main(string[] args)
{
Run(_instance);
}
}
This code is a windows service (there is service specific code in the base class). For some reason the value stored in "a" is always blank in the constructor. Is there something obvious which is doing this, or is it a quirk in the .NET platform?
Swap round the declarations of the _instance and a fields. In C#, static fields are initialized in the order in which they're declared. In other words, your Server constructor is running too early.
Or you could declare a as const, which removes it from the construction process.
The problem is that you're calling the constructor before the initializer for a is run, so you're seeing the default value for a. In fact, it's not blank (an empty string) - it's null. You can fix this by reordering:
public class Service : ServiceBase
{
// Initialize a first
private static readonly string a = #"D:\test.txt";
private static readonly Service _instance = new Service();
...
}
The static initializers are run in the textual order (which becomes somewhat undefined with partial classes). From section 10.5.5.1 of the C# 3.0 spec:
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. If a static
constructor (§10.12) exists in the
class, execution of the static field
initializers occurs immediately prior
to executing that static constructor.
Otherwise, the static field
initializers are executed at an
implementation-dependent time prior to
the first use of a static field of
that class.
I'm not sure I use that would though... it's too easy to break.
Can you change it to const? That would be more robust:
private const string a = #"D:\test.txt";
That way it won't matter if someone changes the order again at a later date, thinking that reordering is a harmless operation. Presumably you were unaware of the importance of the order here, otherwise you wouldn't have asked this question - how willing are you to gamble that another programmer looking at the same code won't have the same issue? :)
Static fields are instantiated in the order they appear in the text file. So your Service is being constructed before the string is initialized. if you swap those two lines it should work.
Link: http://msdn.microsoft.com/en-us/library/aa645758%28VS.71%29.aspx
Oh, and the singleton pattern is often an anti-pattern. Try to avoid using it if possible.

What is a "static" class?

In C# what is the difference between:
public static class ClassName {}
And:
public class ClassName {}
Firstly, a comment on an answer asked about what "static" means. In C# terms, "static" means "relating to the type itself, rather than an instance of the type." You access a static member (from another type) using the type name instead of a reference or a value. For example:
// Static method, so called using type name
Guid someGuid = Guid.NewGuid();
// Instance method, called on a value
string asString = someGuid.ToString();
Now, static classes...
Static classes are usually used as "utility" classes. The canonical example is probably System.Math. It doesn't make sense to create an instance of math - it just "is". A few rules (both "can" and "can't"):
Static classes always derive from object. You can't specify a different base type, or make the static class implement an interface.
Static classes can't have any instance members - all variables, methods etc must be static.
Static classes can't declare any instance constructors and the compiler doesn't create a parameterless constructor by default. (Before static classes came in C# 2.0, people would often create an abstract class with a private constructor, which prevented instantiation. No need here.)
Static classes are implicitly abstract (i.e. they're compiled to IL which describes an abstract class) but you can't add the abstract modifier yourself.
Static classes are implicitly sealed (i.e. they're compiled to IL which describes an sealed class) but you can't add the sealed modifier yourself.
Static classes may be generic.
Static classes may be nested, in either non-static or static classes.
Static classes may have nested types, either non-static or static.
Only static, top-level non-generic classes can contain extension methods (C# 3.0).
A static class cannot be instantiated, and can contain only static members. Hence, the calls for a static class are as: MyStaticClass.MyMethod(...) or MyStaticClass.MyConstant.
A non static class can be instantiated and may contain non-static members (instance constructors, destructor, indexers). A non-static member of a non-static class is callable only through an object:
MyNonStaticClass x = new MyNonStaticClass(...);
x.MyNonStaticMethod(...);
public static class ClassName {}
A static class is just like a global variable: you can use it anywhere in your code without instantiating them.
For example: ClassName. After the dot operator, you can use any property or function of it.
public class ClassName {}
But if you have non-static class then you need to create an instance of this class.
For example:
ClassName classNameObject = new ClassName();
A static class also can not be inherited from, whereas a non-static class with static members can be inherited from.
All methods/properties in a static class must be static, whereas a 'normal' class can contain a mix of instance and static methods.
You can't instantiate (create objects of) a static class. And it can only contain static members.
Example: System.Math
Static class can contain static members only.
Static member can be used without instantiating a class first.
Static classes and members are used to create data and methods that can be accessed without creating an instance (using the new keyword, they cannot have a constructor) of the class.
Static classes can be declared when there is no dependence on the its own object identity, so a static class must contain only static members.
This classes are loaded by the CLR when the program or namespace containing the class is loaded.
They are also sealed, cannot be inherited from.
http://www.javaworld.com/javaworld/javaqa/1999-08/01-qa-static2.html - very good article on this. This is for Java. But i think concept should should same in C# too.
Static variable in c
a variable local to a class as auto variables
but static variable do not disappear as function is no longer active.Their values persist.If control comes back,static variables have same value
static function in c
functions that are not visible to functions in other files.
*static data members in cpp *
data members can be variables or functions in cpp
static applies to both data members
the class itself can be static
"There is only one copy of static data memberss shared by all objects in that class"
static data members can access only static data members
static class
this class cannot instantiate objects
Most importantly, "A static constructor is only called one time, and a static class remains in memory for the lifetime of the application domain in which your program resides." - From Microsoft

Categories

Resources