21

I am trying to decode a piece of code from a book:

List<Person> people = new List<Person>()
{
new Person {FirstName="Homer",LastName="Simpson",Age=47},
new Person {FirstName="Marge",LastName="Simpson",Age=45}
};

Person is just a simple class they made, with a bunch of fields: Name, Last Name, etc...

What I don't understand is, don't we send parameters to a constructor of Person in non-curly brackets? I tried replicating this code, but it doesn't seem to fly, any takers?

Thanks for input.

3
  • 4
  • 1
    "I tried replicating this code, but it doesn't seem to fly" <- you need to be using C# 3 (VS 2008) or later for this syntax to be available.
    – AakashM
    Commented Oct 29, 2012 at 9:41
  • Be aware of the differences between the two concepts: Object Initialization and Object Population. In general you do initialization in the constructor. The method of your example is best used for population not for initialization.
    – NoChance
    Commented Oct 30, 2012 at 5:05

2 Answers 2

37

C# allows you to specify property parameters in curly braces when the object is initialized. This allows you to pick and choose which items to initialize and which to leave as defaults.

A constructor, on the other hand, runs one single block of code with a fixed set of parameters. So to get the same effect you'd have to create multiple constructors all with the various combinations of properties you might want to initialize, which could be tedious.

var x = new Person {FirstName="Homer",LastName="Simpson",Age=47}; 

is exactly equivalent to this:

var x = new Person();
x.FirstName="Homer";
x.LastName="Simpson";
x.Age=47;

Except that it's shorter and arguably easier on the eyes.

It also allows for constructs like you demonstrated in your question, which would be very tedious if you had to create temporary variables and initialize them out as I did here before adding them to the list. (Which is how you used to have to do it.) All without requiring an explicitly-defined constructor that takes your desired list of parameters, which may or may not be available.

Also, note that while a constructor can initialize properties with a private setter, this technique (as should be obvious from the provided example) will only work if you have a public setter for the property. Also note that my shortened example implicitly called the default (parameterless) constructor, which would therefore have to be present.

5
  • Might be worth adding that due to this, the properties initialized in the curly braces must be publicly settable. Commented Oct 29, 2012 at 5:38
  • @YamMarcovic ah. yes. Note added to that effect.
    – tylerl
    Commented Oct 29, 2012 at 5:44
  • 2
    Ah, I am enlightened, excellent explanation. Commented Oct 29, 2012 at 6:25
  • 2
    To get a very similar effect with a single constructor, you could make all of its parameters optional. Then you could do something like new Person(lastName: "Simpson"), leaving out the firstName and age parameters.
    – svick
    Commented Oct 29, 2012 at 8:18
  • This doesn't address why you can't just pass those to the constructor, i.e. var x = new Person("Homer", "Simpson", 47);
    – rayray
    Commented May 15, 2019 at 14:03
1

This is called object initializers syntax as explained here.

It allows to set the values of any accessible field or property of the class typically after the constructor has been called.

The answer by tylerl is great but I want to add some details to it because there is a bit of confusion.

From the linked article:

Object initializers let you assign values to any accessible fields or properties of an object at creation time without having to invoke a constructor followed by lines of assignment statements.

This is only achievable if you haven't defined any constructor and using this syntax and pick and choose which field or property you want to initialize.If you have defined any one constructor, then THAT constructor has to be called first and then you can use this syntax to override the values.

This is demonstrated here. You will get a link error in the code below since we have defined a constructor and I am not calling it.

   public class Cat
    {
        // Auto-implemented properties.
        public int Age { get; set; }
        public string Name { get; set; }

        public string Owner;

         public Cat(string name)
        {
            this.Name = name;
            this.Owner = "Person A";
        }

        public void print()
        {
            Console.WriteLine("Cat: {0}, {1}, {2}", Name, Age, Owner);
        }

    }

    class Program
    {
        static void Main(string[] args)
        {
            // link error below because you have to create proper constructor since I have defined one and signature doesn't match
            Cat cat = new Cat { Age = 3, Owner = "Person B" }; 

            // Note if remove the only constructor, only then constructor is never called and the above will compile fine.

            cat.print();
        }
    }

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.