I have the below code and I have only two simple questions which are normal to expect in the behavior of the program below, which I am not seeing unfortunately:
Static constructor in any class should be the first one to be hit soon after static fields being hit. Then only instance constructor. But what I am seeing is, the debug first goes to the public constructor. Sad thing. Why?
Although: the output of the program is:
This is Staticcc...
1
...Which is correct.
I kept a break point in the Static constructor start, but when I debug it only shows break point in the end brace of static constructor. Why?
Sample code:
public sealed class B : A, C
{
public int? m = 0;
public B()
{
m = 1;
}
private B(int a, int b)
{
m = 2;
}
protected B(int x, int y, int z)
{
m = 3;
}
static B()
{
Console.WriteLine("THis is staticcc");
}
public static B b = new B();
public static B BC
{
get
{
return b;
}
}
static void Main()
{
Console.WriteLine(B.BC.m);
Console.ReadKey();
}
}
public interface C
{
}
public class A
{
//private A()
//{
//}
}
This is the problem:
public static B b = new B();
Static field initializers are executed before the static constructor is executed. From the C# spec section 10.5.5.1:
If a static constructor (10.12) exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor.
Your static field initializer calls your instance constructor, therefore the instance constructor is the first thing to execute.
Although: the output of the program is This is Staticcc... then 1...Which is correct.
Yes, because all of the initialization happens as part of evaluating B.BC.m in Main.
If you add Console.WriteLine("Instance Constructor"); into your constructor, you'll see:
Instance Constructor
THis is staticcc
1
If that doesn't help, think of Main as being this:
int tmp = B.BC.m; // This prints initialization bits
Console.WriteLine(tmp); // This prints 1
That is because this line is ran before the static constructor:
public static B b = new B();
Your first line in the static constructor (the part you don't see, but is actually there) is actually calling the constructor of B. That is the reason you don't see the static constructor hit first.
If you would write it like this, you would see the static constructor hit first:
static B()
{
Console.WriteLine("THis is staticcc");
b = new B();
}
public static B b;
Related
This sample from C# in a Nutshell says it writes 0 followed by 3 due to "the field initializer that instantiates a Foo executes before X is initialized to 3".
class Program {
static void Main() { Console.WriteLine (Foo.X); } // 3
}
class Foo
{
public static Foo Instance = new Foo(); //static field 1
public static int X = 3; //static field 2
Foo() => Console.WriteLine (X); // 0
}
My question is, why does this not go into an infinite recursion due to static field 1 which makes a new Foo (which makes a new Foo, which makes a new Foo, etc.)?
Let's have a look at what's going on. BeforeFoo class addressing static fields must be
initialized.
class Program {
static void Main() {
// Before Foo class is addressed (here Foo.X), Foo must be initialized
Console.WriteLine(Foo.X);
}
}
.Net will do it in order they are mentioned in the class declaration:
class Foo
{
// Will be run first
public static Foo Instance = new Foo();
// Will be run second
public static int X = 3;
Foo() => Console.WriteLine(X);
}
So far so good, Instance start its initialization
public static Foo Instance = new Foo();
constructor Foo() called which prints X: Foo() => Console.WriteLine (X); note,
that since X has not been initialized, 0 will be printed.
X will be initialized, it's now 3
Initialization is completed now, and .Net is ready to adddress Foo class
Console.WriteLine(Foo.X);
and 3 will be printed (note the 2nd step of the initialization)
Static fields and properties are shared across all instances of a class, and get initialized in a special constructor called .cctor that gets called when the class is first referenced.
So the compiled code is something similar to
class Foo
{
public static Foo Instance;
public static int X;
.cctor() {
Instance = new Foo();
X = 3;
}
Foo() => Console.WriteLine (X);
}
The call flow would be Foo::.cctor -> Foo::Foo() -> Foo:get_X().
So there is no recursion, but X will have its default value when .cctor is called.
i have piece of code
public class A
{
public A()
{
Console.WriteLine("A");
}
B b = new B("From A");
}
public class B : A
{
public B()
{
Console.WriteLine("B");
}
public B(string str) //Getting exception here
{
Console.WriteLine("In B " + str);
}
}
public class C : A
{
B b = new B("From C");
public C()
{
Console.WriteLine("C");
}
}
class Program
{
static void Main(string[] args)
{
new C();
Console.ReadKey();
}
}
Here, i know that all properties are initialized first before base constructor called, but i am unable to find why i am getting Stackoverflow exception. Any Help ?? Thanks
Because B inherits from A, it inherits the
B b = new B("From A");
field. So whenever you create a B object it creates another B object, in an infinite recursive chain.
So in the actual Program you have, you create a C object. This then constructs a B object using the overload that takes a string ("From C"). You then get an exception on that constructor, because it then recursively creates infinite B objects.
Recursive infinite loop:
Every time you create a B, you create a new A (through inheritance).
Every time you create an A, you create a new B (through variable b).
Since B inherits from A
//public class B : A
And when you create object of B in class A,It goes in recursive infinite loop.
The problem above is due to cyclic instantiation.
Here our thinking of instantiation causes these kind of issues:
Here when we instantiate C we just do not get object of class C but, it in fact is the combination of C+B+A.
These kind of problems can be easily identified by drawing an object diagram with Arrows from instantiating object to instanted object.
I ran into an interesting bug today, the code below would crash on the commented line on some machines, and not others. The problem appears to be related to ordering of static constructors, vs static initializers, and inheritance.
The fix was to move the code in the #region into another class, but I still don't understand what was actually happening, and why it seemed to only happen on some machines.
I have looked at these two articels:
http://csharpindepth.com/Articles/General/Singleton.aspx
http://csharpindepth.com/Articles/General/BeforeFieldInit.aspx
which shed some insight, but neither goes into how inheritance effects things.
public class CountAggregator : Aggregator
{
private static readonly CountAggregator _instance = new CountAggregator();
public static CountAggregator Instance
{
get
{
return _instance;
}
}
private CountAggregator() : base("CNT")
{
}
}
public class Aggregator
{
protected Aggregator(string id)
{
Id = id;
}
public string Id { get; private set; }
#region All Aggregators
private static readonly List<Aggregator> _allAggregators = new List<Aggregator>();
private static readonly Dictionary<string, Aggregator> _aggregatorsById = new Dictionary<string, Aggregator>();
public static IEnumerable<Aggregator> All
{
get { return _allAggregators; }
}
public static Aggregator GetAggregator(string id)
{
return _aggregatorsById[id];
}
static Aggregator()
{
_allAggregators.AddRange(new Aggregator[]
{
CountAggregator.Instance,
}
foreach (var aggregator in _allAggregators)
{
//this prints false, and the next line crashes
HtmlPage.Window.Alert((aggregator != null).ToString());
_aggregatorsById.Add(aggregator.Id, aggregator);
}
}
#endregion
}
Let's have class B, inheriting class A. The rule of thumb is that when the static constructor of class B is invoked, it first has make sure its ancestor, class A, was initialized before. However, when A's static constructor is initialized first, having a dependency on its ancestor B (which is weird anyway), B's static constructor cannot be executed before A's finishes, which results in any B's field to be in their default (=zero, null) state.
When you first access B anywhere in your code, then the sequence is as follows:
Access B
Invoke B's static constructor
Invoke A's static constructor, if necessary
initialize A's static fields
execute the constructor's code
initialize B's static fields
execute the constructor's code
On the other hand, when you first access A anywhere in your code, then the sequence is as follows:
Access A
Invoke A's static constructor
initialize A's static fields
execute the constructor's code, which includes
Access B and its static field B.Field
Invoke B's static constructor — circular dependency on A, cannot call
return B.Field which is uninitialized i.e. zero / null
use invalid value of B.Field
Your solution to pull out the code contained in the region is very logical and you should have done that anyway because of separation of concerns.
I am new to C# programming.
Please help me.
I created a class Tester:
class Tester
{
public int a = 5;
public int b = a;
}
Question 1 : Why am I not able to use this variable a for initializing the variable b.
Question 2: If I changed the variables to static then it works fine. Why is there a difference?
class Tester
{
public static int a = 5;
public static int b = a;
}
Question 3 : In previous example if I swap the sequence of variable then it works fine why because a is declaring after b . How can it initialize a?
class Tester
{
public static int b = a; // 0
public static int a = 5; // 5
}
There are some icky initialization order issues when you use fields initializers. A simple example would be:
class Test {
int a = b;
int b;
public Test() {
b = 1;
}
}
What will be the value of a? If you use the constructor-initializes-object rule then a will be 1. That however not the way it works under the hood, a would be 0 if the syntax where valid. A side-effect of the way field initializers are implemented, their code is injected into the constructor before the code in the body of the constructor. This problem gets a lot more convoluted when the class inherits base classes that have constructors.
This is too ugly, the C# language designers solved this by simply forbidding this kind of code. The rule is that you cannot reference this in a field initializer, that will create a reference to an object whose class constructor hasn't finished executing.
The rule is relaxed for static fields, there is no this reference and the CLR provides decent guarantees for class initializer execution order. That however doesn't avoid ambiguity, it is an exercise to guess what the field values will be in this example:
class Test {
static int a = b + 1;
static int b = a + 1;
}
Try it and see if you can make sense of the result. It is otherwise well-defined.
Answer1: You cannot use an instance variable to initialize another instance variable. Why? Because the compiler can rearrange these - there is no guarantee that variable "a" will be initialized before "b", so the above line might throw a NullReferenceException.
Answer2: It works fine with static because static are initialize before other variables and their references are not changed.
Please let me know if it helps.
As Anirudh said. You cannot use an instance variable to initialize another instance variable. Why? Because the compiler can rearrange these - there is no guarantee that a will be initialized before b.
You can use constructor for this.
class Tester
{
public int a=5;
public int b;
public Tester()//constructor
{
b=a;
}
}
or
class Tester
{
public static int a = 5;
public static int b;
public Tester()//constructor
{
b = a;
}
}
Ok, I have greatly changed the code to show the actual problem more clearly. I have tested this code, and it definitely fails.
public class MyEnumBase
{
private int _val;
private static Dictionary<int, MyEnumBase> ValueMap = new Dictionary<int, MyEnumBase>();
protected MyEnumBase()
{
_val = ValueMap.Count;
ValueMap.Add(_val, this);
}
public static MyEnumBase ValueOf(int i)
{
return ValueMap[i];
}
public static IEnumerable<MyEnumBase> Values { get { return ValueMap.Values; } }
public override string ToString()
{
return string.Format("MyEnum({0})", _val);
}
}
public class Colors : MyEnumBase
{
public static readonly Colors Red = new Colors();
public static readonly Colors Green = new Colors();
public static readonly Colors Blue = new Colors();
public static readonly Colors Yellow = new Colors();
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("color value of 1 is " + Colors.ValueOf(2));
}
}
The following code fails because the Colors constructor is never called before ValueOf() is called. Is there a clean way to ensure that all my static fields are called before I call ValueOf?
Thanks,
~S
Static fields get initialized before you use them. Exact time depends on implementation and you should not make any assumptions about it. Static fields 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
(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.
The code that you posted should work:
Child.TimesConstructed()
will not print 0 if you access one of the children (Child.C1) prior to this call.