2009-10-05 10 views
3

J'ai une classe qui a une propriété de type string [].Ajouter un élément à une chaîne [] tableau

Je dois créer un autre élément de tableau, dois-je réinitialiser la taille et copier tous les éléments précédents?

+6

C'est pourquoi il existe tellement de classes de collection. – Will

+0

Vous voudrez peut-être ajouter plus de détails ... est-ce votre propre code qui est de type 'chaîne []', ou fait-il partie d'une API que vous ne pouvez pas éditer? Quelle version de C# utilisez-vous? (Cela pourrait invalider la plupart des réponses listées ici!) –

Répondre

14

Vous pouvez utiliser Array.Resize qui préservera le contenu du tableau.

par exemple.

var array = myClass.SomeArrayProperty; 
Array.Resize(ref array, newSize); 
myClass.SomeArrayProperty = array; 

Vous devez utiliser une variable temporaire parce que les propriétés ne peuvent pas être utilisées comme arguments ref.

+1

Ceci, en interne, fait essentiellement une réaffectation + copie, cependant, c'est toujours une exigence. –

+0

exemple de code? La propriété de la classe est string [] – mrblah

+2

Oui, bien sûr; les tableaux ont une taille fixe. Cependant, la question était "do * I * have to" et la réponse est non, car cette fonctionnalité est intégrée. –

1

Oui. Les tableaux ont une taille fixe.

De C# Spécification:

12,2 création Array
...
Lorsqu'une instance de tableau est créé, le rang et longueur de chaque dimension sont établie et restent constantes pour la durée de vie entière de l'instance . En d'autres termes, il n'est pas possible de changer le rang d'une instance de tableau existante , ni de de redimensionner ses dimensions.

Vous pouvez également jeter un oeil à blog d'Eric Lippert Arrays considered somewhat harmful

5

Oui, si vous souhaitez pouvoir ajouter des éléments de manière dynamique, utilisez un List.

Bien qu'il soit recommandé de ne pas exposer List en tant que propriété, utilisez plutôt IList<string> ou IEnumerable<String>.

6

Si c'est votre classe, vous devriez probablement changer la propriété d'utiliser un IList<string>, ICollection<string> ou IEnumerable<string>, selon la façon dont vous anticipez cette propriété sera utilisée. Ensuite, quel que soit ceux que vous choisissez de retourner de la fonction, essayez d'utiliser un List<string> dans le type lui-même.

1

Je préférerais copier la chaîne [] à Liste < chaîne>, effectuer toutes les manipulations, puis .ToArray() pour produire la chaîne résultante [].

+3

Wow, c'était dur, et aucune raison pour laquelle c'était une pratique si horrible? –

+1

Je suis intéressé à savoir aussi. Peut-être commencer une nouvelle question décrivant votre réponse et demander pourquoi c'est mauvais? –

+0

Fixer avec un upvote. C'est une solution décente si la propriété est un tableau de chaînes qu'il ne possède pas et ne peut pas contrôler. –

0

Contrôlez-vous la classe? Si c'est le cas, pensez à utiliser List<string> à la place.

(Et pendant que vous y êtes, pensez à utiliser IList<string> dans votre API publique au lieu de string[].)

3

J'utiliser une liste si possible. C'est beaucoup plus facile à gérer. Évidemment, cela dépend si c'est votre classe et votre capacité à le faire sans aucun problème.

List<string> myList = new List<string>(); 
      myList.Add("item"); 
      myList.Remove("item"); 

Si votre devoir utiliser des tableaux puis utilisez

Array.Resize

0

Il est plus facile de travailler avec List<T>, mais si vous ne contrôlez pas la propriété ce n'est pas une option. Notez que ceci est vu couramment dans les proxies générés par soap, mais IIRC il y a un commutateur de ligne de commande que vous pouvez employer si vous préférez des listes aux matrices.

Notez que si vous faites cela régulièrement, une méthode d'extension peut être utile:

public static T[] Append<T>(this T[] arr, T item) { 
    Array.Resize(ref arr, arr == null ? 1 : (arr.Length + 1)); 
    arr[arr.Length-1] = item; 
    return arr; 
} 

que vous pouvez ensuite utiliser pour votre propriété:

obj.SomeProp = obj.SomeProp.Append(someValue); 

(notez que cela fonctionne même si obj.SomeProp est null, en créant un tableau de longueur 1)

S'il s'agissait d'un champ/variable, un simple argument ref pourrait également fonctionner:

public static void Append<T>(ref T[] arr, T item) { 
    Array.Resize(ref arr, arr == null ? 1 : (arr.Length + 1)); 
    arr[arr.Length-1] = item; 
} 
Questions connexes