2013-08-02 2 views
7

Я делаю обзор кода и нашел строку, в которой один из наших разработчиков является создание объекта с помощью пустой инициализатор объекта, как это:Есть ли недостатки в использовании инициализатора пустого объекта?

List<Floorplan> floorplans = new List<Floorplan> { }; 

Я не знаю, почему он инстанцирует этот путь, а не :

List<Floorplan> floorplans = new List<Floorplan>(); 

Есть ли какие-либо недостатки в создании объектов с использованием пустых инициализаторов объектов? Помимо стилистически непоследовательного, я хочу знать, есть ли причина избежать такого подхода. Что-то говорит мне, что это пахнет, но я хочу быть уверенным, прежде чем что-нибудь скажу.

+2

'var floorplans = new Список ();' лучший ИМО. Нет недостатков. –

+6

Если у вас есть сомнения, проверьте IL. Инициализаторы коллекции - это просто синтаксический сахар. –

+2

FYI - ReSharper по умолчанию будет вызывать предупреждение о пустом инициализаторе объектов. –

ответ

10

Скомпилированный результат тот же.

Следующая C#:

static void Main() 
{ 
    var x = new List<int>(); 
    var y = new List<int> { }; 
} 

компилирует в следующий 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 

Если добавить значение в коллекции:

static void Main() 
{ 
    var x = new List<int>(); 
    x.Add(1); 
    var y = new List<int> { 1 }; 
} 

Это результирующее 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 

Это показывает, как инициализаторы сбора только синтаксис сахара. Поскольку инициализаторы коллекции не были первоначально частью C#, я думаю, что люди больше привыкли к синтаксису конструктора. Если бы я натолкнулся на какой-то код, который использовал пустой инициализатор коллекции, я бы задался вопросом, почему, но у него, конечно же, нет каких-либо серьезных проблем с читабельностью. Если кто-то достаточно умен, чтобы понимать код вообще, то {} против () не должен так огорчиться, что он подрывает способность понимать, что делает код.Это сводится к вопросу. Сделайте то, что ваша команда соглашается, и если это только вы, то используйте его в своем сердце.

+0

+1 для тщательного ответ и объяснение. – evanmcdonnal

1

Нет причин, по которым необходимо использовать инициализацию { }, поэтому я бы сказал, удалите ее. Разработчик использует инициализатор статической коллекции. Единственная причина, по которой вы это сделаете, чтобы вы могли начать сбор с некоторых предметов, учитывая, что их нет, на самом деле это не имеет смысла. При этом результат будет пустой коллекцией, как если бы он вызвал конструктор в обычном режиме.

+0

Но разве не было бы разницы во внутренней емкости? – Esailija

+0

@ Эсаилия - это риторический? Однако определенно может быть, что базовый массив не может иметь длину 0, поэтому я собираюсь предположить, что он получает емкость по умолчанию. – evanmcdonnal

+0

Нет, просто вопрос, чтобы бросить вызов быстрым предположениям, что они действительно одинаковы. Я действительно понятия не имел, но это могло быть возможно. – Esailija

3

В этом случае нет недостатков, кроме как удобство чтения. Если вам не нужны дополнительные скобки при создании экземпляра, не используйте их просто и просто.

Я бы даже зашел так далеко, как говорят о производительности. Многие ответы здесь идут глубже, пытаясь ответить на этот вопрос. Даже если один из методов был лучше, чем другой, мы говорим о том, что действительно представляет собой микро-оптимизация.

1

Они в основном одинаковы, но использование конструктора по умолчанию более читаемо.

0

Есть много комментариев, говорящих, что «конструктор по умолчанию более читабельен». Нет веских оснований полагать, что () больше (или меньше) читается, чем {}, поэтому вы фактически проводите опрос общественного мнения здесь.

Если вы беспокоитесь о правильности, код вашего коллеги в порядке. Если вас беспокоят стандарты кодирования, вы должны убедиться, что код изменен в соответствии с вашим стандартом (независимо от того, какой стандарт может быть).

+0

'Нет веских оснований полагать, что() более (или менее) читается, чем {}' Я ', не уверен, что это правда. Помните, что синтаксис инициализатора был просто включен в C# 3.0, я думаю, так что есть много старых код, который использует синтаксис '()' и синтаксис '()', сопоставим обратно. Это может не иметь значения для всех, но еще две причины, по которым выбор - это не просто «опрос общественного мнения» – chollida

+1

«Просто» в C# 3.0? Это означает, что эта функция составляет 6 лет. Нет никакой веской причины не использовать новые функции, особенно одну, такую ​​как «новая». –

+0

, пожалуйста, не защищайтесь :) Все, что я имел в виду, это то, что некоторые люди оказались в ловушке ориентируясь на более старые версии. Это просто факт жизни. Использование этой функции означает, что вы официально отказались от поддержки старых версий. Это может не иметь значения для вас, но каждый разработчик должен знать о компромиссах, которые они делают. – chollida

Смежные вопросы