I'm doing a code review and found a line where one of our developers is creating an object using an empty object initializer like this:
List<Floorplan> floorplans = new List<Floorplan> { };
I don't know why he would instantiate this way rather than:
List<Floorplan> floorplans = new List<Floorplan>();
Are there any downsides to object instantiation using empty object initializers? Other than being stylistically inconsistent I want to know if there is a reason avoid this approach. Something tells me this smells but I want to be sure before I say anything.
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.
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.
Constructor is a special non-static member function of a class that is used to initialize objects of its class type. In the definition of a constructor of a class, member initializer list specifies the initializers for direct and virtual bases and non-static data members.
The compiled result is the same.
The following C#:
static void Main()
{
var x = new List<int>();
var y = new List<int> { };
}
Compiles into the following IL:
.method private hidebysig static
void Main () cil managed
{
// Method begins at RVA 0x2050
// Code size 14 (0xe)
.maxstack 1
.entrypoint
.locals init (
[0] class [mscorlib]System.Collections.Generic.List`1<int32> x,
[1] class [mscorlib]System.Collections.Generic.List`1<int32> y
)
IL_0000: nop
IL_0001: newobj instance void class [mscorlib]System.Collections.Generic.List`1<int32>::.ctor()
IL_0006: stloc.0
IL_0007: newobj instance void class [mscorlib]System.Collections.Generic.List`1<int32>::.ctor()
IL_000c: stloc.1
IL_000d: ret
} // end of method Program::Main
If you add a value to the collections:
static void Main()
{
var x = new List<int>();
x.Add(1);
var y = new List<int> { 1 };
}
This is the resulting IL:
.method private hidebysig static
void Main () cil managed
{
// Method begins at RVA 0x2050
// Code size 32 (0x20)
.maxstack 2
.entrypoint
.locals init (
[0] class [mscorlib]System.Collections.Generic.List`1<int32> x,
[1] class [mscorlib]System.Collections.Generic.List`1<int32> y,
[2] class [mscorlib]System.Collections.Generic.List`1<int32> '<>g__initLocal0'
)
IL_0000: nop
IL_0001: newobj instance void class [mscorlib]System.Collections.Generic.List`1<int32>::.ctor()
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldc.i4.1
IL_0009: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<int32>::Add(!0)
IL_000e: nop
IL_000f: newobj instance void class [mscorlib]System.Collections.Generic.List`1<int32>::.ctor()
IL_0014: stloc.2
IL_0015: ldloc.2
IL_0016: ldc.i4.1
IL_0017: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<int32>::Add(!0)
IL_001c: nop
IL_001d: ldloc.2
IL_001e: stloc.1
IL_001f: ret
} // end of method Program::Main
This shows how collection initializers are only syntax sugar. Because collection initializers were not originally part of C#, I think people are more used to the constructor syntax. If I came across some code that used an empty collection initializer, I would wonder to myself why, but it certainly doesn't have any severe readability issues. If one is intelligent enough to understand code at all, then {}
vs ()
shouldn't be so upsetting that it undermines one's ability to comprehend what the code is doing. It comes down to a matter of opinion. Do what your team agrees on, and if it's just you, then use it to your hearts content.
There are no downsides but favor readability in this case. If you don't need the extra brackets while instantiating then don't use them plain and simple.
I would even go as far as saying favor productivity. A lot of the answers here are going deeper in trying to answer this question. Even if one technique was better than the other we're talking about what's really a micro optimization.
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