2

I've always wondered this. In C#, when do instance variables with default values get set - before or after the constructor?

For this code:

public class Foo
{
  public int bar=1;
  public Foo()
  {
    bar = 2;
  }
}
...
Console.WriteLine(new Foo().bar);

Would it output 1 or 2?

0

6 Answers 6

4

The instance during construction will run through all declarations first then proceed into the constructor itself.

Thus, bar = 1 will execute before bar = 2 but the end result will still be bar = 2.

Sign up to request clarification or add additional context in comments.

Comments

1

It will return 2, you are accessing the attribute after the constructor has modified it.

Comments

1

The member instantiations are added first in the constructor. If you check out the IL code that is actually created using Reflector, this is what the compiler does with it:

.class auto ansi nested public beforefieldinit Foo
  extends [mscorlib]System.Object
{
  .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
  {
    .maxstack 8
    L_0000: ldarg.0 
    L_0001: ldc.i4.1 
    L_0002: stfld int32 Test.Program/Foo::bar
    L_0007: ldarg.0 
    L_0008: call instance void [mscorlib]System.Object::.ctor()
    L_000d: nop 
    L_000e: nop 
    L_000f: ldarg.0 
    L_0010: ldc.i4.2 
    L_0011: stfld int32 Test.Program/Foo::bar
    L_0016: nop 
    L_0017: ret 
  }

  .field public int32 bar

}

So, the member instantiations are placed first in the constructor, then it calls the constructor of the base type, then comes the code that you put in the constructor.

Comments

0

Why don't you test this?

When instantiating a class object, you essentially create an instance of the class, then run the constructor function. Therefore, it should output 2

5 Comments

I probably could have tested it... but i figured that here, i might get some reasoning behind why it's the way it is.
I'm not very fond of the "Try it yourself" or "google it yourself" answers that seem to be so much more common these days. While I agree that people should make an effort to figure things out themselves first before asking a question, it's very offputting and people may be afraid to ask questions if they think they're going to get a typical "RTFM! you loser" comment like happens so often in various open source forums.
If you read the question and my answer, you'll see that my answer has "some reasoning behind why it's the way it is". When someone puts a piece of code then asks "Would it output 1 or 2?", I can't help but answer the way I did. Sometimes good answers require good questions. SO questions shouldn't serve as C# compilers.
Also, Chris, I recommend editing your question with something along the lines of "why does it output 1 or 2".
@Mystere Man This forum is not to make others do the effort,instead it is to solve any difficulties ,without giving a try if any question s posted it is inevitable to receive "Try it yourself" or "google it yourself" answers.
0

The underlying bytecode doesn't have any special ability to initialize these values before calling a constructor. The C# compiler is responsible for the ordering, which is emitted as bytecode in a method called .ctor for the type:

If the constructor does not specify this(...) as a chained constructor, meaning it either specifies base(...) or nothing at all, then it:

  1. Set the value for all fields with initializers.
  2. Calls the constructor for the base class. If no specific one is specified, it calls the default one.
  3. Runs the code you typed in your constructor.

If the constructor specifies this(...) as a chained constructor, the order is slightly different because the chained constructor will handle the initialization of fields.

  1. Call the chained constructor, which is the one you explicitly indicated with : this(...).
  2. Run the code you typed in your constructor.

Comments

0

If this didn't happen, it could create some very confusing and unintuitive situations. Like if something in your constructor acted in a particular way depending on the initial value of bar, it would have no idea if it had been initialised (or worse, bar was a user defined class rather than an int. Is it null because the constructor of that class wanted it to be? Or has it just not been initialised?) It helps to think of constructors as the birth process of you class, like the point a baby actually pops out of it's Mummy, and initialisation as the growing in the womb. Pre-conditions such as initialisation are a given - you wouldn't see a baby born with no arms, and then suddenly they appeared an hour later would you?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.