Object initializers in .NET framework (Part I)

Vishvvas
Posted by in .NET Framework category on for Intermediate level | Points: 250 | Views : 6320 red flag

With C# 3.0, Microsoft has introduced the object initializers which are very handy in scenarios for hundreds of perperties with no specific/ adequate constructors, eliminating the issues of additional efforts in already deployed types when there are changes in properties/ member variables etc.

Objective

To explore the initializes in .NET framework and its usage scenarios.

Introduction


Initialization of objects is a fundamental concept in OOPs and we are aware how it is done in .NET framework. The most obvious way is through constructors where a constructor performs the initialization (refer Example#1). Another way is property-style programming, i.e. using fine-grained getters and setters (refer Example#2).

Although initialization through constructor is most preferred and used way, it has its own limitations. First scenario is where there are hundreds of properties where in to provide the initialization through constructor becomes clumsy. We can have multiple (by overload) constructors but it complicates the implementation and also would confuse the user as when and which constructor to be used. Mostly in such scenarios the setter way of initialization is employed but this way also sometime become impracticable. Another scenario is that the libraries consisting such types are already deployed and the underlying types need to undergo changes like addition or member variables and properties. In this scenario, option of providing an additional constructor in already deployed code would incur additional efforts for deployment, maintenance and may be there won’t be strong reason for additional constructor. Next option is use setter initialization but it would have different implementation at different places adding confusion and making the maintenance difficult. Also the use of setters always results in fragmented code which would hamper the readability and it is developer dependent i.e. if developer forgets to do the setting then there could be some vulnerability involved and would be difficult to debug. As it may be few properties, having a child class is won’t be a viable option. So is there any better option?  YES, it’s there.

But with C# 3.0, this problem is tackled with object Initializers. In the Part I we will explore through object initializers keeping collection initializers for next part.

Description

Let’s explore the object initializers. These initializers allow programmers to initialize a type object in a declarative manner at the time of creation of object without explicitly invoking the constructor.  The compiler processes the object initializers by first accessing the default instance constructor, and then by processing the member initializations.

Let’s see the examples. Assume we have a class “Person” which is already deployed and has only one constructor.


public class Person

    {

        public string FirstName { getset; }

        public string LastName { getset; }

        public string MiddleName { getset; }

     

        public int PersonId { getset; }

 

        public Person(string firstName, string lastName)

        {

            this.FirstName = firstName;

            this.LastName = lastName;

        }

}

Example # 1: Initialization through constructor

Person objPerson = new Person("Tom", "Harry");

 

Example # 2: Initialization through setters

In cases when there are many properties/member variables to be initialized then it’s a preferred way to use setters to initialize in conjunction with constructor initialization (may be default in case if any constructor is not provided. In this example the persons middle name is set through setter.

 

   Person objPerson = new Person("Tom", "Harry");

            objPerson.MiddleName = "Dick";

 

Example#3: Initializers through object initializers

 

Person objPersonThroughObjectInitializer = new Person { FirstName = "TomObject", LastName = "HarryObject",  MiddleName = "DickObject" };

 

For hundreds of such properties /variable (which is very common in ORM kind of applications i.e. LINQTO SQL, EF) it becomes very clumpy to provider multiple constructors as it would depend upon the situation. For the deployed libraries, providing additional constructors can make the vulnerability and also would be difficult for versioning, maintaining. Another option would be sub-classing but for few additions again it won’t be good choice considering the additional efforts for sub-classing , deploying and maintaining. Setters are always available but as discussed above  it makes the implementation combination of constructor and setter making it difficult to read, comprehend and change. The best option in this scenario is using object initializers.

 

Example #4 : Object Initializers with anonymous types.

Object initializers can be used In any context but in case of LINQ expressions they can be particularly useful as such expressions uses anonymous types very frequently which has only one option for initialization i.e. object initialization.


var anonymousPerson = new { FirstName = "TomAnonymous", LastName = "HarryAnonymous", MiddleName = "DickAnonymous" };

 


class Program

    {

static void Main(string[] args)// for Object Initializers

        {

             Console.WriteLine("*********************Object Initilizers****************************************");

            Person objPersonThroughConstructor = new Person("Tom""Harry");           

            Console.WriteLine("Initialization through Constructor: The person's name is " + objPersonThroughConstructor.FirstName + " " + objPersonThroughConstructor.LastName + " " + objPersonThroughConstructor.MiddleName);

            objPersonThroughConstructor.MiddleName = "Dick";

            Console.WriteLine("Initialization through Constructor and setter: The person's name is " + objPersonThroughConstructor.FirstName + " " + objPersonThroughConstructor.LastName + " " + objPersonThroughConstructor.MiddleName);

            // Make the similar declaration by using a object initializer and sending arguments for the first and last names. The default constructor is  invoked in processing this declaration

            //not the constructor that has two parameters.

            Person objSamePersonThroughObjectInitializer = new Person { FirstName = "SimilarTom", LastName ="SimilarHarry" };

            Console.WriteLine("Initialization through object initializers: The person's name is  " + objSamePersonThroughObjectInitializer.FirstName + " " + objSamePersonThroughObjectInitializer.LastName );

            // Make another declaration by using a object initializer and sending arguments for the first, middle and last names. No corresponding constructor is

            // defined in the class.           

            Person objPersonThroughObjectInitializer = new Person { FirstName = "TomObject", LastName = "HarryObject", MiddleName = "DickObject" };

          

            Console.WriteLine("Initialization through object initializers: The person's name is  " + objPersonThroughObjectInitializer.FirstName + " " + objPersonThroughObjectInitializer.LastName + " " + objPersonThroughObjectInitializer.MiddleName);

            // Make another declaration by using a object initializer and sending arguments for the first, middle and last names but not mentioning the type.No corresponding constructor is

            // defined in the class.        

            var anonymousPerson = new { FirstName = "TomAnonymous", LastName = "HarryAnonymous", MiddleName ="DickAnonymous" };

            Console.WriteLine("Initialization through object initializers for anonymous type: The person's name is " + anonymousPerson.FirstName + " " + anonymousPerson.LastName + " " + anonymousPerson.MiddleName);

           Console.WriteLine("*****************************************************************************");

        }

}



Output


Let’s run the program and see the output.

*********************Object Initilizers****************************************

Initialization through Constructor: The person's name is Tom Harry

Initialization through Constructor and setter: The person's name is Tom Harry Dick

Initialization through object initializers: The person's name is  SimilarTom SimilarHarry

Initialization through object initializers: The person's name is  TomObject HarryObject DickObject

Initialization through object initializers for anonymous type: The person's name

 is TomAnonymous HarryAnonymous DickAnonymous

*****************************************************************************


Summary


The output demonstrates the usage of different initializers and their results. The use of object initializers is easy and pretty straightforward. Intelligence helps to choose all the properties/ member variables which are public giving the user a definite control on his usage. If the default constructor is not provided or declared as private in the class, object initializers who require public access will fail.


Conclusion

In a way, object initializers give a shorthand method for initialization rather it can be considered as an additional constructor which doesn’t exist in the type definition.

So there are no more headaches in scenarios where additional properties/variable needed to be initialized without providing/invoking constructors or fragmenting code with setter way or extending such type. In a nutshell, this would eliminate lot of development efforts, deployment effort and maintenance efforts simultaneously having a very clean implementation.

Happy Programming!!!!!

Page copy protected against web site content infringement by Copyscape

About the Author

Vishvvas
Full Name: Vishwas Sutar
Member Level: HonoraryPlatinum
Member Status: Member,MVP
Member Since: 5/30/2011 2:13:10 AM
Country: India

http://www.dotnetfunda.com
Extensive and rich experience across gamut of technologies and programming languages like PB,VB,C++,VB.NET, C#, Classic ASP,ASP.NET, ASP.NET MVC.

Login to vote for this post.

Comments or Responses

Login to post response

Comment using Facebook(Author doesn't get notification)