#838 – Object and Collection Initializers as Parameters

You can use object and collection initializers to initialize an object or collection when it is declared.  You can also use an object initializer anywhere that an instance of the corresponding object is expected.  And you can use a collection initializer wherever an instance of the collection is expected.

This means that we can use initializers to create an object passed as a parameter to a method.

Suppose that we have the following methods defined in a Dog class:

        public static void DoSomethingWithDog(Dog d)
        {
            d.Bark("Woof");
            d.Fetch();
        }

        public void BarkPlaylist(List<string> barkList)
        {
            foreach (string s in barkList)
                Bark(s);
        }

We can pass an object initializer that creates a new Dog instance to the DoSomethingWithDog method.  And we can pass a collection initializer to the BarkPlaylist method.

            // Object initializer as parameter
            Dog.DoSomethingWithDog(new Dog { Name = "Kirby", Age = 15 });

            // Collection initializer as parameter
            myDog.BarkPlaylist(new List<string> { "Woof", "Growf", "Blurp" });

#837 – Object Initializers within Collection Initializers

Recall that you can initialize a collection when it is declared, using a collection initializer.

            List<Dog> myDogs = new List<Dog>
            {
                new Dog("Kirby", 15),
                new Dog("Ruby", 3)
            };

Also recall that, instead of invoking a constructor, you can initialize an object by using an object initializer.

            Dog myDog = new Dog { Name = "Kirby", Age = 15 };

You can combine these techniques, using object initializers within collection initializers.

            List<Dog> myDogs = new List<Dog>
            {
                new Dog { Name = "Kirby", Age = 15 },
                new Dog { Name = "Ruby", Age = 3 }
            };

#836 – Initializing a Generic List with an Object Initializer

Instead of using the Add method repeatedly to populate a generic list, you can use an object initializer to initialize the contents of the list when you declare it.

The object initializer used to initialize a generic list consists of a set of braces, with a comma-separated list of elements within the braces.  If the list’s type is a reference type, each element in the list is instantiated using the new operator.

This use of an object initializer, in initializing a collection, is known as a collection initializer.

            // List of integers
            List<int> favNumbers = new List<int> { 5, 8, 42 };

            // List of Dog objects
            List<Dog> myDogs = new List<Dog>
            {
                new Dog("Kirby", 15),
                new Dog("Ruby", 3)
            };

836-001

#704 – Using an Object Initializer with Any Constructor

One common pattern for using an object initializer to initalize select properties or fields of an object is to use the following syntax.

            Dog d = new Dog { Name = "Bowzer", Age = 2 };

When using this syntax, the default (parameterless) constructor for the class is called. After the object is constructed, the specified values are assigned to the appropriate properties.

You can also  construct the object using any custom constructor, followed by an object initializer.

For example, let’s say that the Dog class only has a single constructor, which takes two arguments to set the Name and Age properties.  You can then do the following:

            Dog d = new Dog("Bowzer", 2) { CollarSize = 12.4 };

The constructor is called, setting Name and Age. After the object is constructed, the CollarSize property is initialized to contain a value of 12.4.

#703 – Object Initializers Allow Setting Either Fields or Properties

When you use an object initializer, you can specify the value that one or more of the object’s properties should take on, after the object is constructed.

Dog d = new Dog { Name = "Bowzer", Age = 2 };

If your class includes public fields, you can also initialize the fields within the object initializer.

For example:

    public class Dog
    {
        // Properties
        public string Name { get; set; }
        public int Age { get; set; }

        // Field
        public double CollarSize;

        // Constructors
        public Dog()
        {
        }
    }
            Dog d2 = new Dog { Name = "Kirby", Age = 15, CollarSize = 12.2 };

#656 – Nested Object Initializers

When using an object initializer to initialize the contents of an object, you can nest an inner object initializer to initialize an object that is referenced by a property of the outer object.

Assume that we have the following two classes:

    public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int BirthYear { get; set; }
    }

    public class Movie
    {
        public string Title { get; set; }
        public int Year { get; set; }
        public Person Director { get; set; }
        public Person LeadActor { get; set; }
    }

We might then initialize a Movie object as follows:

            Movie aMovie = new Movie
            {
                Title = "Psycho",
                Year = 1960,
                Director = new Person { FirstName = "Alfred", LastName = "Hitchcock", BirthYear = 1899 },
                LeadActor = new Person { FirstName = "Anthony", LastName = "Perkins", BirthYear = 1932 }
            };

#655 – Initializing Only Some Properties with An Object Initializer

Using an object initializer, you can initialize an object by specifying values for its public properties, as long as the object’s type defines a parameterless constructor.

Movie aMovie = new Movie { Title = "Life Is Beautiful", Year = 1997, Director = "Roberto Benigni" };

Using this syntax, you can initialize any subset of the objects properties that you like. Any properties not initialized will take on default values.

            Movie movie = new Movie { Title = "Fight Club", Year = 1999 };
            Movie movie2 = new Movie { Year = 1972, Director = "Francis Ford Coppola" };
            Movie movie3 = new Movie { Title = "Taxi Driver" };


You could even use an empty object initializer, which would be equivalent to invoking the parameterless constructor directly.

            Movie movie4 = new Movie { };
            Movie movie5 = new Movie();