Here's a simple question : Is there any (performance) difference between this :
Person person = new Person() { Name = "Philippe", Mail = "[email protected]", };
and this
Person person = new Person(); person.Name = "Philippe"; person.Mail = "[email protected]";
You can imagine bigger object with more properties.
Initializing an ObjectThis class contains a single constructor. You can recognize a constructor because its declaration uses the same name as the class and it has no return type. The constructor in the Point class takes two integer arguments, as declared by the code (int a, int b).
An object initializer is an expression that describes the initialization of an Object . Objects consist of properties, which are used to describe an object. The values of object properties can either contain primitive data types or other objects.
In object initializer, you can initialize the value to the fields or properties of a class at the time of creating an object without calling a constructor. In this syntax, you can create an object and then this syntax initializes the freshly created object with its properties, to the variable in the assignment.
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.
They are almost exactly equivalent except that the first method (using an object initializer) only works in C# 3.0 and newer. Any performance difference is only minor and not worth worrying about.
They produce almost identical IL code. The first gives this:
.method private hidebysig instance void ObjectInitializer() cil managed { .maxstack 2 .locals init ( [0] class Person person, [1] class Person <>g__initLocal0) L_0000: newobj instance void Person::.ctor() L_0005: stloc.1 L_0006: ldloc.1 L_0007: ldstr "Philippe" L_000c: callvirt instance void Person::set_Name(string) L_0011: ldloc.1 L_0012: ldstr "[email protected]" L_0017: callvirt instance void Person::set_Mail(string) L_001c: ldloc.1 L_001d: stloc.0 L_001e: ldloc.0 L_001f: callvirt instance string [mscorlib]System.Object::ToString() L_0024: pop L_0025: ret }
The second gives this:
.method private hidebysig instance void SetProperties() cil managed { .maxstack 2 .locals init ( [0] class Person person) L_0000: newobj instance void Person::.ctor() L_0005: stloc.0 L_0006: ldloc.0 L_0007: ldstr "Philippe" L_000c: callvirt instance void Person::set_Name(string) L_0011: ldloc.0 L_0012: ldstr "[email protected]" L_0017: callvirt instance void Person::set_Mail(string) L_001c: ldloc.0 L_001d: callvirt instance string [mscorlib]System.Object::ToString() L_0022: pop L_0023: ret }
As you can see, nearly identical code is generated. See below for the exact C# code I compiled.
Performance measurements show very similar results with a very small performance improvement for using the object initializer syntax:
Method Iterations per second ObjectInitializer 8.8 million SetProperties 8.6 million
Code I used for testing the performance:
using System; class Person { public string Name { get; set; } public string Mail { get; set; } } class Program { private void ObjectInitializer() { Person person = new Person() { Name = "Philippe", Mail = "[email protected]", }; person.ToString(); } private void SetProperties() { Person person = new Person(); person.Name = "Philippe"; person.Mail = "[email protected]"; person.ToString(); } private const int repetitions = 100000000; private void Time(Action action) { DateTime start = DateTime.UtcNow; for (int i = 0; i < repetitions; ++i) { action(); } DateTime end = DateTime.UtcNow; Console.WriteLine(repetitions / (end - start).TotalSeconds); } private void Run() { Time(ObjectInitializer); Time(SetProperties); Console.WriteLine("Finished"); Console.ReadLine(); } private static void Main() { new Program().Run(); } }
One additional thing worth noting is this:
If you fail to handle an exception in your constructor, you'll get a TypeInitializationException. While that may not seem so bad, the truth is that it conceals the real cause of the problem, and makes it harder to track down.
If, on the other hand, you use an object initializer, you're invoking each property individually outside of the constructor, and any thrown exceptions will be very clear and very evident: they won't be masked by the TypeInitializationException.
In general, it's a bad idea to throw exceptions in a constructor. If you want to avoid that scenario, go with the initializer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With