Thursday, September 11, 2014

Object Initializers, Collection Initializers and Custom Collection Initializers in C#

In this wiki let’s see how we can write a custom collection initializer. Before going straight to the topic let’s refresh our brains on Object Initializers and Collection Initializers.

Object Initializers


Let’s say you have the following class named “Employee”.
public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
}
“Employee” class has two properties “Id” and “Name”. So this is how we can initialize a object of type “Employee” and set the values for it’s properties in the classical way.
Employee employee = new Employee();
employee.Id = 1;
employee.Name = "Jaliya Udagedara";
So notice here that there are three lines of code, and the more you have properties, the more lines of code you have to write just for setting up values for properties. Now let’s have a look at how we can do the same using the Object Initializer of the class Employee.
Employee employee = new Employee()
{
    Id = 1,
    Name = "Jaliya Udagedara"
};
Even though there seems to be many lines of codes here, technically it’s just a one line. Note that even you can remove the parenthesis next to Employee and right the object initializer in the following way. It will still work.
Employee employee = new Employee
{
    Id = 1,
    Name = "Jaliya Udagedara"
};

Collection Initializers


Collection initializers works in the same way as Object Initializers and it lets you add one or more elements when you initialize a collection class that implements IEnumerable. The collection class must be implementing IEnumerable, otherwise you won’t be able to use collection initializer, please take a note of that. You will later understand why the collection has to be implementing IEnumerable.

Now let’s see how we used to add items to a collection in the classical way.
List<Employee> employees = new List<Employee>();
employees.Add(new Employee() { Id = 1, Name = "Jaliya Udagedara" });
Here I have first created an List of type Employee and added a new Employee. And to add new Employee I have used it’s object initializer. Now let’s see how we can use the collection initializer to do the same.
List<Employee> employees = new List<Employee>()
{
    new Employee()
    {
        Id = 1,
        Name = "Jaliya Udagedara"
    }
};
So what happens here is by using a collection initializer you don't have to specify multiple calls to the Add method. Behind the scene when the source is compiling the compiler calls the Add method of the respective collection. So for that compiler needs the collection class to be implemented IEnumerable and to have an public method named Add. So here the List<T> is implementing IEnumerable. 

So now let’s see how we can define a custom collection class (same is List<T>) which can be initialized using the collection initializer.

I am modifying the previous “Employee” class by adding a public constructor which takes two values in and set values to it’s properties.
public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
 
    public Employee(int id, string name)
    {
        Id = id;
        Name = name;
    }
}
Now I have the following Custom collection class named “EmployeeCollection” and it’s implementing IEnumerable of type Employee. Here I am adding a public method named "Add" which takes two parameters so as the constructor of the Employee.
public class EmployeeCollection : IEnumerable<Employee>
{
    private readonly List<Employee> employees;
 
    public EmployeeCollection()
    {
        employees = new List<Employee>();
    }
 
    public void Add(int id, string name)
    {
        employees.Add(new Employee(id, name));
    }
 
    public IEnumerator<Employee> GetEnumerator()
    {
        return employees.GetEnumerator();
    }
 
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}
Now let’s see my custom “EmployeeCollection” in action. By calling public Add method I can still add Employees.
EmployeeCollection employees = new EmployeeCollection();
employees.Add(1, "Jaliya Udagedara");
And this is how we can use the collection initializer on my custom “EmployeeCollection”.
EmployeeCollection employees = new EmployeeCollection()
{
    {1, "Jaliya Udagedara"}
};
So that’s it. I am uploading the sample to my OneDrive.


Happy Coding.

Regards,
Jaliya