Как инициализировать список <T>для заданного размера (в отличие от емкости)? - PullRequest
90 голосов
/ 21 января 2009

.NET предлагает универсальный контейнер списков, производительность которого практически идентична (см. Вопрос «Производительность массивов и списков»). Однако они довольно разные по инициализации.

Массивы очень легко инициализировать значением по умолчанию, и по определению они уже имеют определенный размер:

string[] Ar = new string[10];

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

Ar[5]="hello";

со списком вещей сложнее. Я вижу два способа сделать одну и ту же инициализацию, ни один из которых вы бы не назвали элегантным:

List<string> L = new List<string>(10);
for (int i=0;i<10;i++) L.Add(null);

или

string[] Ar = new string[10];
List<string> L = new List<string>(Ar);

Что было бы чище?

РЕДАКТИРОВАТЬ: ответы до сих пор относятся к емкости, которая является чем-то иным, чем предварительное заполнение списка. Например, в только что созданном списке с емкостью 10 нельзя сделать L[2]="somevalue"

РЕДАКТИРОВАТЬ 2: Люди задаются вопросом, почему я хочу использовать списки таким образом, поскольку они не предназначены для использования. Я вижу две причины:

  1. Можно довольно убедительно утверждать, что списки являются массивами «следующего поколения», добавляя гибкость практически без штрафа. Поэтому их следует использовать по умолчанию. Я подчеркиваю, что их не так просто инициализировать.

  2. То, что я сейчас пишу, - это базовый класс, предлагающий функциональные возможности по умолчанию как часть большей структуры. В функциональности по умолчанию, которую я предлагаю, размер списка известен заранее, и поэтому я мог бы использовать массив. Однако я хочу предложить любому базовому классу возможность динамически расширять его, и поэтому я выбираю список.

Ответы [ 13 ]

0 голосов
/ 20 ноября 2016

Это образец, который я использовал для моего модульного теста. Я создал список объектов класса. Затем я использовал forloop для добавления числа «X» объектов, которые я ожидаю от сервиса. Таким образом, вы можете добавить / инициализировать список для любого заданного размера.

public void TestMethod1()
    {
        var expected = new List<DotaViewer.Interface.DotaHero>();
        for (int i = 0; i < 22; i++)//You add empty initialization here
        {
            var temp = new DotaViewer.Interface.DotaHero();
            expected.Add(temp);
        }
        var nw = new DotaHeroCsvService();
        var items = nw.GetHero();

        CollectionAssert.AreEqual(expected,items);


    }

Надеюсь, я вам помог, ребята.

0 голосов
/ 09 ноября 2016

Уведомление об IList: MSDN IList Замечания : «Реализации IList делятся на три категории: только для чтения, фиксированного размера и переменного размера. (...). Для общей версии этого интерфейса см. System.Collections.Generic.IList<T> ".

IList<T> НЕ наследует от IList (но List<T> реализует и IList<T>, и IList), но всегда переменного размера . Начиная с .NET 4.5, у нас также есть IReadOnlyList<T>, но AFAIK, нет универсального List фиксированного размера, который был бы тем, что вы ищете.

0 голосов
/ 24 ноября 2014

Вы можете использовать Linq для умной инициализации вашего списка со значением по умолчанию. (Подобно ответу Дэвида Б. .)

var defaultStrings = (new int[10]).Select(x => "my value").ToList();

Пройдите на один шаг дальше и инициализируйте каждую строку различными значениями «строка 1», «строка 2», «строка 3» и т. Д .:

int x = 1;
var numberedStrings = (new int[10]).Select(x => "string " + x++).ToList();
...