Gridview Bound with Properties of Nested Class

Understanding C# field initialization requirements

Field initialization come before base class constructor call, so it is not a valid object. Any method call with this as argument at this point leads to unverifiable code and throws a VerificationException if unverifiable code is not allowed. For example: in security transparent code.

  • 10.11.2 Instance variable initializers
    When an instance constructor has no constructor initializer, or it has a constructor initializer of the form base(...), that constructor implicitly performs the initializations specified by the variable-initializers of the instance fields declared in its class. This corresponds to a sequence of assignments that are executed immediately upon entry to the constructor and before the implicit invocation of the direct base class constructor. The variable initializers are executed in the textual order in which they appear in the class declaration.
  • 10.11.3 Constructor execution
    Variable initializers are transformed into assignment statements, and these assignment statements are executed before the invocation of the base class instance constructor. This ordering ensures that all instance fields are initialized by their variable initializers before any statements that have access to that instance are executed.

Field initialization

You cannot make use of the this keyword when initializing fields inline. The reason for this is the order in which the code is executed: for all intents and purposes, the code to initialize a field inline is run before the constructor for the class (i.e. the C# compiler will prevent access to the this keyword). Basically what that means is this will not compile:

public class Class1
{
private SomeClass someclass = new SomeClass(this);

public Class1()
{
}
}

but this will:

public class Class1
{
private SomeClass someclass;

public Class1()
{
someclass = new SomeClass(this);
}
}

It's a subtle difference, but one worth making a note of.

The other differences between the two versions are only really noticeable when using inheritance. If you have two classes which inherit from each other, the fields in the derived class will be initialized first, then the fields in the base class will be initialized, then the constructor for the base class will be invoked, and finally, the constructor for the derived class will be invoked. There are some cases where you need to be very careful with this, as it could cause a fruit salad of complications if you don't realise what is going on (one of which involves calling a virtual method inside the base class constructor, but that is almost never a wise move). Heres an example:

class BaseClass
{
private readonly object objectA = new object(); // Second
private readonly object objectB;

public BaseClass()
{
this.objectB = new object(); // Third
}
}

class DerivedClass : BaseClass
{
private object objectC = new object(); // First
private object objectD;

public DerivedClass()
{
this.objectD = new object(); // Forth
}
}

You will need to set breakpoints on all of the lines that initialize fields to be able to see the correct sequence.

static field initialization explanation and its requirement

When a type has a static constructor, the runtime is constrained to execute all type initialization immediately before the first use of any member of the type.

When it doesn't have a static constructor, the runtime has much more freedom - it has to execute the type initializer at some point before the first use of a static field or before an instance is constructed, but that's all. You can even observe static methods which don't touch static fields being executed without the type initializer executing.

In your case, both A and B have static constructors, and the order of access to the members is B first, then A, hence your output. Without those static constructors, you'd still be guaranteed to get "1 1" as the last line, and you'd still get both "Init A" and "Init B", but the ordering of them wouldn't be guaranteed.

This is just the way the language and runtime are specified - and usually it has no impact, as usually type initializers should just be setting up the type, with no other side effects. Type initializers should do as little as possible, ideally - if they fail for some reason, the type will never be usable; type initializers aren't retried.

For more details, see my beforefieldinit article and .NET 4.0 type initializer changes blog post.

Initialize class fields in constructor or at declaration?

My rules:

  1. Don't initialize with the default values in declaration (null, false, 0, 0.0…).
  2. Prefer initialization in declaration if you don't have a constructor parameter that changes the value of the field.
  3. If the value of the field changes because of a constructor parameter put the initialization in the constructors.
  4. Be consistent in your practice (the most important rule).

Forcing all class fields be initialized

Providing a constructor that takes all properties as parameter, as NDJ said, is a good idea.

If you really want to get a warning or an error on compilation in case you forgot to update your constructor after adding a new property, you could build a custom Code Analysis rule (using the FxCop SDK) and check that every setter of public properties is called in the class constructor.

Why can't a member field have a field initializer call a member function?

Field initializers run before constructors, in the reverse order of constructors. That is, they run from the most derived type up to the least derived type, and the least derived type's fields will be initialized before any of the constructors are called. A design decision was made not to allow this to be referenced before the base type's constructor has been called, or perhaps, more generally, not to allow references to a partially constructed instance from a field initializer.

I think it's a sensible decision. If you are not intimately familiar with the language, the state of the object when a field initializer runs is less clear than when a constructor runs. The way in which a constructor declaration flows reflects the actual order in which constructors are called, so it's easier to reason about the state. Specifically, the : base() call appears before the constructor body, implying the base constructor has already run by the time you enter the body. You cannot infer the object's state as easily at a field declaration site, and in fact the field initialization order differs from Java, which was arguably the most similar mainstream language when C# was introduced.

Static field initialization Order in C#

Why only Class B is getting executed first?

The specification is saying that both outputs are valid. But a specific combination of a compiler and runtime (e.g. the compiler for C# 7.0 running on .Net Framework 4.7) can decide to be more strict and behave consistently.

It seems the combination you're using decides to first initialize static fields of the class that is used first, and doing that is acceptable according to the specification.

How can I simulate the uncertain behavior?

Again, the specification does not require any uncertainty.

If you really wanted to make it behave that way, you could modify an existing .Net runtime (like CoreCLR, Mono or DotNetAnywhere), to find all the possible orders of initialization and then choose one at random.

Static field initialization order (C#) - can someone explain this snippet?

In C#, primitive types such as int take on a default value. For int, the default value is 0. This is not like C++ where you have to initialize the value or it will be getting a random dirty value from memory. Since Y is known to be of type int, X can be assigned it's default value of 0.

As far as the keyword ctor, I don't see it used very much as a C# programmer, but I am familiar with the term. I believe it is used in a few places in Visual Studio, for instance in the object browser.



Related Topics



Leave a reply



Submit