.NET propose un conteneur de liste générique dont les performances sont presque identiques (voir la question Performances des tableaux par rapport aux listes). Cependant, ils sont assez différents dans 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:
string[] Ar = new string[10];
Ce qui permet d'attribuer en toute sécurité des éléments aléatoires, par exemple:
Ar[5]="hello";
avec la liste, les choses sont plus délicates. Je peux voir deux façons de faire la même initialisation, dont aucune n'est ce que vous appelleriez élégant:
List<string> L = new List<string>(10);
for (int i=0;i<10;i++) L.Add(null);
ou
string[] Ar = new string[10];
List<string> L = new List<string>(Ar);
Quelle serait une manière plus propre?
EDIT: Les réponses jusqu'à présent se réfèrent à la capacité, qui est autre chose que pré-peupler une liste. Par exemple, sur une liste qui vient d'être créée avec une capacité de 10, on ne peut pas faireL[2]="somevalue"
EDIT 2: Les gens se demandent pourquoi je veux utiliser les listes de cette façon, car ce n'est pas la façon dont elles sont destinées à être utilisées. Je peux voir deux raisons:
On pourrait affirmer de manière assez convaincante que les listes sont les tableaux de la «prochaine génération», ajoutant de la flexibilité avec presque aucune pénalité. Il faut donc les utiliser par défaut. Je souligne qu'ils ne seront peut-être pas aussi faciles à initialiser.
Ce que j'écris actuellement est une classe de base offrant des fonctionnalités par défaut dans le cadre d'un cadre plus large. Dans la fonctionnalité par défaut que j'offre, la taille de la liste est connue à l'avance et j'aurais donc pu utiliser un tableau. Cependant, je souhaite offrir à toute classe de base la possibilité de l'étendre dynamiquement et j'opte donc pour une liste.
List
ne remplace pasArray
. Ils résolvent des problèmes bien distincts. Si vous voulez une taille fixe, vous voulez un fichierArray
. Si vous utilisez aList
, vous ne le faites pas correctement.Réponses:
Je ne peux pas dire que j'en ai besoin très souvent - pouvez-vous nous expliquer pourquoi vous le souhaitez? Je le mettrais probablement comme une méthode statique dans une classe d'assistance:
Vous pourriez utiliser,
Enumerable.Repeat(default(T), count).ToList()
mais ce serait inefficace en raison du redimensionnement de la mémoire tampon.Notez que si
T
est un type de référence, il stockera descount
copies de la référence passée pour levalue
paramètre - ainsi elles feront toutes référence au même objet. Cela peut ou non être ce que vous voulez, selon votre cas d'utilisation.EDIT: Comme indiqué dans les commentaires, vous pouvez
Repeated
utiliser une boucle pour remplir la liste si vous le souhaitez. Ce serait aussi un peu plus rapide. Personnellement, je trouve le codeRepeat
plus descriptif et je soupçonne que dans le monde réel, la différence de performance ne serait pas pertinente, mais votre kilométrage peut varier.la source
Enumerable.Repeat(...).ToArray()
, ce n'est pas comme ça que je l'utilise.Enumerable.Repeat()
de la manière suivante (implémentéePair
comme l'équivalent C ++): enEnumerable.Repeat( new Pair<int,int>(int.MaxValue,-1), costs.Count)
remarquant l'effet secondaire, que leList
était plein de copies référencées vers un seul objet. Changer un élément commemyList[i].First = 1
changer chaque élément dans l'ensembleList
. Il m'a fallu des heures pour trouver ce bug. Connaissez-vous une solution à ce problème (sauf pour utiliser une boucle commune et l'utiliser.Add(new Pair...)
?la source
L
réutiliserait simplement la mémoire destring[10]
telle quelle (le stockage de sauvegarde d'une liste est également un tableau) ou allouerait-elle une nouvelle mémoire et copierait ensuite le contenu destring[10]
?string[10]
récupérera automatiquement les déchets siL
sélectionne la dernière route.Utilisez le constructeur qui prend un int ("capacité") comme argument:
EDIT: Je dois ajouter 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 en premier lieu.
EDIT2:
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 ce soit maladroit démontre que cela va à l'encontre de l'utilisation prévue de la classe.
la source
new List<string>()
qui concerne le problème . Bien joué pour avoir obtenu autant de votes positifs :)list[index] = obj;
et d'utiliser d'autres fonctionnalités de liste.Créez d'abord un tableau avec le nombre d'éléments souhaités, puis convertissez le tableau en liste.
la source
Pourquoi utilisez-vous une liste si vous souhaitez l'initialiser avec une valeur fixe? Je peux comprendre que - pour des raisons de performances - vous vouliez lui donner une capacité initiale, mais n'est-ce pas l'un des avantages d'une liste par rapport à une matrice régulière qu'elle peut augmenter en cas de besoin?
Lorsque vous faites ceci:
Vous créez une liste dont la capacité est de 100 entiers. Cela signifie que votre liste n'aura pas besoin de «grandir» tant que vous n'aurez pas ajouté le 101e élément. Le tableau sous-jacent de la liste sera initialisé avec une longueur de 100.
la source
Initialiser le contenu d'une liste comme celle-là n'est pas vraiment à quoi servent les listes. Les listes sont conçues pour contenir des objets. Si vous souhaitez mapper des nombres particuliers à des objets particuliers, envisagez d'utiliser une structure de paires clé-valeur telle qu'une table de hachage ou un dictionnaire au lieu d'une liste.
la source
Vous semblez insister sur la nécessité d'une association positionnelle avec vos données, alors un tableau associatif ne serait-il pas plus approprié?
la source
Si vous souhaitez initialiser la liste avec N éléments d'une valeur fixe:
la source
Vous pouvez utiliser Linq pour initialiser intelligemment votre liste avec une valeur par défaut. (Similaire à la réponse de David B. )
Allez un peu plus loin et initialisez chaque chaîne avec des valeurs distinctes "chaîne 1", "chaîne 2", "chaîne 3", etc:
la source
la source
La réponse acceptée (celle avec la coche verte) a un problème.
Le problème:
Je recommande de changer la ligne ci-dessus pour effectuer une copie de l'objet. Il existe de nombreux articles différents à ce sujet:
Si vous souhaitez initialiser chaque élément de votre liste avec le constructeur par défaut, plutôt que NULL, ajoutez la méthode suivante:
la source
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, reportez-vous à
System.Collections.Generic.IList<T>
.»IList<T>
n'hérite PAS deIList
(maisList<T>
implémente les deuxIList<T>
etIList
), mais est toujours de taille variable . Depuis .NET 4.5, nous avons égalementIReadOnlyList<T>
mais AFAIK, il n'y a pas de liste générique de taille fixe qui serait ce que vous recherchez.la source
Ceci est un exemple que j'ai utilisé pour mon test unitaire. J'ai créé une liste d'objets de classe. Ensuite, j'ai utilisé forloop pour ajouter le nombre "X" d'objets que j'attends du service. De cette façon, vous pouvez ajouter / initialiser une liste pour n'importe quelle taille donnée.
J'espère que j'ai été utile pour vous les gars.
la source
Un peu tard mais la première solution que vous proposez me semble bien plus propre: vous n'allouez pas deux fois la mémoire. Même le constructeur de liste a besoin de parcourir le tableau pour le copier; il ne sait même pas d'avance qu'il n'y a que des éléments nuls à l'intérieur.
1. - allouer N - boucle N Coût: 1 * allouer (N) + N * loop_iteration
2. - allouer N - allouer N + loop () Coût: 2 * allouer (N) + N * loop_iteration
Cependant, l'allocation et les boucles de List pourraient être plus rapides puisque List est une classe intégrée, mais C # est compilé jit sooo ...
la source