Étant donné une List
dans c #, existe-t-il un moyen de l’étendre (dans la limite de ses possibilités) et de définir les nouveaux éléments sur null
? Je voudrais quelque chose qui fonctionne comme un memset
. Je ne cherche pas de sucre ici, je veux un code rapide. Je savais qu’en C l’opération pouvait se faire de 1 à 3 asm par entrée.
La meilleure solution que j’ai trouvée est la suivante :
list.AddRange(Enumerable.Repeat(null, count-list.Count));
Cependant, c = 3.0 (<3.0 est préférable) et pourrait générer et évaluer un énumérateur.
Mon code actuel utilise:
while(list.Count < lim) list.Add(null);
c’est donc le sharepoint départ du coût en temps.
La motivation pour cela est que je dois définir le nième élément, même si c’est après l’ancien comte.
Le moyen le plus simple est probablement de créer un tableau temporaire:
list.AddRange(new T[size - count]);
Où size
est la nouvelle taille requirejse et count
est le nombre d’éléments de la liste. Toutefois, pour des valeurs relativement importantes de ( size - count
, cela peut entraîner de mauvaises performances, car la liste peut être réaffectée plusieurs fois. *
) Il présente également l’inconvénient d’allouer un tableau temporaire supplémentaire qui, selon vos besoins, peut ne pas être acceptable. Vous pouvez atténuer ces deux problèmes au désortingment d’un code plus explicite, en utilisant les méthodes suivantes:
public static class CollectionsUtil { public static List EnsureSize (this List list, int size) { return EnsureSize(list, size, default(T)); } public static List EnsureSize (this List list, int size, T value) { if (list == null) throw new ArgumentNullException("list"); if (size < 0) throw new ArgumentOutOfRangeException("size"); int count = list.Count; if (count < size) { int capacity = list.Capacity; if (capacity < size) list.Capacity = Math.Max(size, capacity * 2); while (count < size) { list.Add(value); ++count; } } return list; } }
Le seul C # 3.0 ici est l’utilisation du modificateur " this
" pour en faire des méthodes d’extension. Supprimez le modificateur et cela fonctionnera en C # 2.0.
Malheureusement, je n’ai jamais comparé les performances des deux versions, je ne sais donc pas laquelle est la meilleure.
Oh, et saviez-vous que vous pourriez redimensionner un tableau en appelant Array.Resize
? Je ne savais pas ça. 🙂
Mettre à jour:
( *
) L'utilisation de list.AddRange(array)
ne provoquera pas l'utilisation d' un énumérateur. En examinant plus en profondeur, Reflector a montré que le tableau sera converti en ICollection
et que la propriété Count
sera utilisée afin que l’atsortingbution ne soit effectuée qu’une fois.
static IEnumerable GetValues (T value, int count) { for (int i = 0; i < count; ++i) yield return value; } list.AddRange(GetValues
Cela fonctionnera avec 2.0+
Pourquoi voulez-vous faire cela ? Le principal avantage d’une liste est qu’elle peut s’agrandir selon les besoins. Pourquoi voulez-vous lui append un certain nombre d’éléments nuls ou par défaut?
Ne vaut-il pas mieux que vous utilisiez un tableau dans ce cas?