Jeff
Jeff

Reputation: 668

Are there any downsides to using an empty object initializer?

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.

Upvotes: 8

Views: 747

Answers (5)

Ralph Caraveo
Ralph Caraveo

Reputation: 10225

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.

Upvotes: 3

Dan
Dan

Reputation: 9837

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.

Upvotes: 10

alc
alc

Reputation: 1557

There are a lot of comments saying "the default constructor is more readable". There's no good reason to assume that () is more (or less) readable than {}, so you're effectively taking an opinion poll here.

If you're worried about correctness, your colleague's code is fine. If you're worried about coding standards, you should make sure that the code is changed to match your standard (whatever that standard may be).

Upvotes: 0

evanmcdonnal
evanmcdonnal

Reputation: 48096

There is no reason why the { } initialization should be used there so I would say remove it. The dev is using the static collection initializer. The only reason you would is so that you can start the collection off with some items, given there are none it doesn't really make sense. That being said, the result will be an empty collection just like if he called the constructor normally.

Upvotes: 1

Cam Bruce
Cam Bruce

Reputation: 5689

They are basically the same, but using the default constructor is more readable.

Upvotes: 1

Related Questions