views:

59

answers:

4

I am trying to use Object initializers to set the properties of a class and then access them within the constructor of the class. The problem is that the properties do not seem to be set until after the constructor runs. Am I doing something wrong.

Basic Class..

public class TestClass
{
    public string FirstName{get; set;}

    public TestClass(){
       NewClass nc = NewClass(FirstName);
    }

}

Client Class

public class ClientClass
{
   public ClientClass(){
      TestClass tc = new TestClass{ FirstName="Jimmy"};
   }
}
A: 

No you are not doing anything wrong. That's how objects initializers work. They call the constructor first in order to obtain a reference to the object and only after set the properties. It's just syntactic sugar.

Darin Dimitrov
+9  A: 

Object initialisers are really syntactic-sugar. Given:

var person = new Person() { Name = "Matt" };

The compiler will change this to:

Person person = new Person();
person.Name = "Matt";

(well, actually its IL variant)

The constructor will always be executed before any property sets. It's quite important when creating a constructor that you pass in any parameters are required to correctly initialise your type. In your example, you require FirstName, so why not pass that in as a constructor parameter?

public TestClass(string firstName) { }
Matthew Abbott
+1  A: 
TestClass tc = new TestClass { FirstName = "Jimmy" };

is syntactic sugar for

TestClass tc = new TestClass();

tc.FirstName = "Jimmy";

and therefore the expected result is what you observe - the properties are assigned after the constructor executed.

Object invariants should be established by the constructor and not be violated during the lifetime of the object (or more practical invariant violations should be short-lived and not visible to the external world). Therefore you really should pass the first name as a constructor parameter if it is important for establishing object invariants.

In my opinion field initializers are heavily overused. Always keep in mind that you can force the caller to provide constructor arguments but not to set some properties after constructing a new instance.

Daniel Brückner
A: 

Just like the other answers said. What you might do is use a constructor to set the FirstName:

public TestClass(string firstName){
   FirstName = firstName;
   NewClass nc = NewClass(FirstName);
}
David Radcliffe