Given this Java code, this outputs 0 and 4:
class A{
A() { print(); }
void print() { System.out.println("A"); }
}
class B extends A{
int i = Math.round(3.5f);
public static void main(String[] args){
A a = new B();
a.print();
}
void print() { System.out.println(i); }
}
And with this identical C# code, this outputs 4 and 4
using System;
class A{
internal A() { print(); }
virtual internal void print() { Console.WriteLine("A"); }
}
class B : A{
int i = (int) Math.Round(3.5f);
public static void Main(string[] args){
A a = new B();
a.print();
}
override internal void print() { Console.WriteLine(i); }
}
Though I figure out that the output should be 4 and 4 on Java, but the answer is actually 0 and 4 on Java. Then I tried it in C#, the answer is 4 and 4
What gives? Java rationale is, during construction of B, A is still initializing(consequently I posit B is still initializing if Java said A is still initializing), so the default value should be 0. Hence the output is 0 and 4 in Java.
Why does C# constructor behavior differ from Java, or vice versa?
It’s happening because of differences in the ordering of object initialisation in constructors.
What is happening in Java:
What is happening in C#:
Neither is right or wrong – it’s just a difference in how the compiler orders the construction operations. Personally I think the Java ordering is a marginally more logical, because it makes sense to me that the superclass is fully constructed before the subclass initialisation takes place.
Either way, because the logic can get quite complicated, I’d suggest that you avoid calling virtual methods during object construction in general.