Использует ли исходный набор исходный объем с помощью установленного в исходном порядке инициализатора?

Использует ли битварный инициализатор типа коллекции его емкость или вам все еще нужно указать его?

То есть:

var list = new List<string>(){ "One", "Two" };

приводят к следующему:

var list = new List<string>(2){ "One", "Two" };

Ответ 1

Инициализатор объектов просто вызывает Add для каждого элемента.

var list = new List<string>{ "One", "Two", "Three" };

Как вы можете видеть, в этом случае вызывается конструктор без параметров:

L_0000: nop 
L_0001: newobj instance void [mscorlib]System.Collections.Generic.List`1<string>::.ctor()
L_0006: stloc.1 
L_0007: ldloc.1 
L_0008: ldstr "One"
L_000d: callvirt instance void [mscorlib]System.Collections.Generic.List`1<string>::Add(!0)
L_0012: nop 
L_0013: ldloc.1 
L_0014: ldstr "Two"
L_0019: callvirt instance void [mscorlib]System.Collections.Generic.List`1<string>::Add(!0)
L_001e: nop 
L_001f: ldloc.1 
L_0020: ldstr "Three"
L_0025: callvirt instance void [mscorlib]System.Collections.Generic.List`1<string>::Add(!0)
L_002a: nop 
L_002b: ldloc.1 

Итак, вы должны установить емкость вручную:

var list = new List<string>(5){ "One", "Two", "Three" };

Скомпилируется в:

L_0000: nop 
L_0001: ldc.i4.5 
L_0002: newobj instance void [mscorlib]System.Collections.Generic.List`1<string>::.ctor(int32)
// rest is same

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

ПРИМЕЧАНИЕ. Я знаю, что емкость по умолчанию равна 4 для List<T>, и я проверил, что произойдет, если мы передадим более 4 элементов в инициализаторе (например, возможно, компилятор определяет, какой конструктор будет вызывать в зависимости от количества элементов), но результат тот же - безразмерный конструктор вызывается по умолчанию.

Я думаю, что назначение инициализаторов коллекции создает небольшие коллекции (1 - 8 элементов), поэтому будет небольшое влияние на производительность (только одно изменение размера, если вы передадите 8 элементов в инициализатор). Никто не ожидает, что вы будете использовать инициализацию на месте с 100 элементами. И если вы собираетесь это сделать, вы должны использовать соответствующий конструктор коллекции.

Ответ 2

Инициализатор коллекции использует доступные методы Add для добавления элементов в коллекцию. Поэтому поведение будет таким же, как использование пустого конструктора с вызовом метода Add.

Собственно, компилятор изменит синтаксис инициализатора объекта на вызовы методу Add. Таким образом, независимо от того, используете ли вы инициализатор объекта, это не имеет значения. Важно то, решите ли вы использовать перегрузку конструктора и количество элементов, которые вы фактически добавляете.

Ответ 3

В соответствии с документацией и учитывая, что инициализатор объекта afer имеет счет 2, он также в конечном итоге также установит емкость.

Емкость всегда больше или равна Count

Ответ 4

После того, как List инициализируется конструктором без аргументов, внутренний массив устанавливается в массив длиной 0.

Когда Add(), Insert() или InsertRange() называются пропускной способностью списка, пересчитываются:

  • Если в списке нет других элементов, емкость устанавливается равной 4 (емкость по умолчанию).
  • Если есть другие элементы, емкость установите в два раза количество элементов.

Если вы укажете емкость, внутренний массив будет создан с таким размером.

Литература: DotNet Источник: RefSrc\Source.NET 4.5\4.5.50709.0\net\ndp\clr\src\BCL\System\Collections\Generic\List.cs\597531\List.cs