Comment initialiser une liste à une taille donnée (par opposition à la capacité)?

.NET propose un conteneur de liste générique dont les performances sont quasiment identiques (voir Performance des tableaux vs. question des listes). Cependant, ils sont très différents lors de l’initialisation.

Les tableaux sont très faciles à initialiser avec une valeur par défaut et, par définition, ils ont déjà une certaine taille:

ssortingng[] Ar = new ssortingng[10]; 

Ce qui permet d’affecter des éléments aléatoires en toute sécurité, disons:

 Ar[5]="hello"; 

avec la liste les choses sont plus délicates. Je peux voir deux manières de faire la même initialisation, ni l’une ni l’autre, ce que vous appeleriez élégant:

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

ou

 ssortingng[] Ar = new ssortingng[10]; List L = new List(Ar); 

Quelle serait une façon plus propre?

EDIT: Les réponses à ce jour se rapportent à la capacité, qui est autre chose que le pré-remplissage d’une liste. Par exemple, sur une liste qui vient d’être créée avec une capacité de 10, on ne peut pas faire L[2]="somevalue"

EDIT 2: Les gens se demandent pourquoi je veux utiliser les listes de cette façon, car ce n’est pas la manière dont ils sont destinés à être utilisés. Je peux voir deux raisons:

  1. On pourrait argumenter de manière très convaincante que les listes sont les baies de «prochaine génération», ajoutant de la flexibilité avec presque aucune pénalité. Par conséquent, il faut les utiliser par défaut. Je souligne qu’ils peuvent ne pas être aussi faciles à initialiser.

  2. Ce que je suis en train d’écrire, c’est une classe de base offrant des fonctionnalités par défaut dans le cadre d’un cadre plus vaste. Dans la fonctionnalité par défaut que je propose, la taille de la liste est connue à l’avance et j’aurais donc pu utiliser un tableau. Cependant, je veux offrir à toute classe de base la possibilité de l’étendre de manière dynamic et, par conséquent, j’opte pour une liste.

Je ne peux pas dire que j’en ai besoin très souvent – pourriez-vous donner plus de détails sur ce que vous voulez? Je le mettrais probablement comme une méthode statique dans une classe d’assistance:

 public static class Lists { public static List RepeatedDefault(int count) { return Repeated(default(T), count); } public static List Repeated(T value, int count) { List ret = new List(count); ret.AddRange(Enumerable.Repeat(value, count)); return ret; } } 

Vous pouvez utiliser Enumerable.Repeat(default(T), count).ToList() mais cela serait inefficace en raison du redimensionnement du tampon.

EDIT: Comme indiqué dans les commentaires, vous pouvez faire en sorte que Repeated utilise une boucle pour remplir la liste si vous le souhaitez. Ce serait un peu plus rapide aussi. Personnellement, je trouve le code utilisant Repeat plus descriptif, et soupçonne que dans le monde réel la différence de performance serait sans importance, mais votre kilométrage peut varier.

 List L = new List ( new ssortingng[10] ); 

Utilisez le constructeur qui prend un int (“capacity”) comme argument:

 List = new List(10); 

EDIT: Je devrais append que je suis d’accord avec Frederik. Vous utilisez la liste d’une manière qui va à l’encontre de tout le raisonnement derrière son utilisation.

EDIT2:

EDIT 2: Ce que je suis en train d’écrire est une classe de base offrant des fonctionnalités par défaut dans le cadre d’un cadre plus vaste. Dans la fonctionnalité par défaut que je propose, la taille de la liste est connue à l’avance et j’aurais donc pu utiliser un tableau. Cependant, je veux offrir à toute classe de base la possibilité de l’étendre de manière dynamic et, par conséquent, j’opte pour une liste.

Pourquoi quelqu’un aurait-il besoin de connaître la taille d’une liste avec toutes les valeurs nulles? S’il n’y a pas de valeurs réelles dans la liste, je m’attendrais à ce que la longueur soit égale à 0. Quoi qu’il en soit, le fait que cela soit désordonné montre que cela va à l’encontre de l’usage prévu du cours.

Pourquoi utilisez-vous une liste si vous souhaitez l’initialiser avec une valeur fixe? Je peux comprendre que, pour des raisons de performance, vous voulez lui donner une capacité initiale, mais n’est-ce pas l’un des avantages d’une liste par rapport à une masortingce régulière qu’elle peut évoluer en cas de besoin?

Lorsque vous faites cela:

 List = new List(100); 

Vous créez une liste dont la capacité est de 100 entiers. Cela signifie que votre liste n’aura pas besoin de se développer tant que vous n’aurez pas ajouté le 101ème élément. Le tableau sous-jacent de la liste sera initialisé avec une longueur de 100.

L’initialisation du contenu d’une liste comme celle-ci ne correspond pas vraiment aux listes. Les listes sont conçues pour contenir des objects. Si vous souhaitez mapper des nombres particuliers à des objects particuliers, envisagez d’utiliser une structure de paire clé-valeur telle qu’une table de hachage ou un dictionnaire au lieu d’une liste.

Si vous souhaitez initialiser la liste avec N éléments de valeur fixe:

 public List InitList(int count, T initValue) { return Enumerable.Repeat(initValue, count).ToList(); } 

Vous semblez insister sur la nécessité d’une association de position avec vos données, alors un tableau associatif ne serait-il pas plus adapté?

 Dictionary foo = new Dictionary(); foo[2] = "ssortingng"; 

Créez un tableau avec le nombre d’éléments souhaité en premier, puis convertissez le tableau en une liste.

 int[] fakeArray = new int[10]; List list = fakeArray.ToList(); 

Cela dépend vraiment de la raison pour laquelle vous voulez l’initialiser. Je ne suis pas sûr que l’initialisation avec un certain nombre d’éléments vides ou nuls soit utile. L’avantage des listes est qu’elles peuvent croître au besoin.

Le constructeur de liste prend un paramètre de capacité qui peut être utilisé pour le remplir initialement.

 List = new List(10); 
 ssortingng [] temp = new ssortingng[] {"1","2","3"}; List temp2 = temp.ToList(); 

Vous pouvez utiliser Linq pour initialiser intelligemment votre liste avec une valeur par défaut. (Similaire à la réponse de David B. )

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

Aller plus loin et initialiser chaque chaîne avec des valeurs distinctes “ssortingng 1”, “ssortingng 2”, “ssortingng 3”, etc.:

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

Une remarque concernant IList: MSDN IList Remarques : “Les implémentations IList se répartissent en trois catégories: lecture seule, taille fixe et taille variable. (…). Pour la version générique de cette interface, voir System.Collections.Generic.IList . ”

IList n’hérite PAS d’ IList (mais List implémente à la fois IList et IList ), mais est toujours de taille variable . Depuis .NET 4.5, nous avons également IReadOnlyList mais AFAIK, il n’y a pas de liste générique de taille fixe qui serait ce que vous cherchez.

Ceci est un exemple que j’ai utilisé pour mon test unitaire. J’ai créé une liste d’objects de classe. Ensuite, j’ai utilisé forloop pour append le nombre d’objects «X» que j’attends du service. De cette façon, vous pouvez append / initialiser une liste pour une taille donnée.

 public void TestMethod1() { var expected = new List(); 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); } 

J'espère que je vous ai aidé les gars.

Un peu tard, mais la première solution que vous avez proposée me semble beaucoup plus claire: vous n’affectez pas la mémoire deux fois. Even List constrcutor doit parcourir le tableau pour le copier. il ne sait même pas à l’avance qu’il n’y a que des éléments nuls à l’intérieur.

1. – atsortingbuer N – loop N Coût: 1 * allocate (N) + N * loop_iteration

2. – allouer N – allouer N + loop () Coût: 2 * allocate (N) + N * loop_iteration

Cependant, l’allocation d’une liste peut être plus rapide car List est une classe intégrée, mais C # est compilé avec jit …