2009-02-18 8 views
3

Ai-je raison de penser que l'extrait suivant ne fonctionne pas (les éléments du tableau ne sont pas modifiés) car le tableau est un entier qui est un type de valeur. La même chose s'appliquerait si l'exemple utilisait un tableau de chaînes, vraisemblablement parce que la chaîne est immuable.C# using Array.ForEach Action Prédire avec un tableau de type valeur ou chaîne

La question que j'est: -

Y at-il un moyen de contourner cela? Je ne peux pas changer la signature de la méthode de rappel - par exemple en ajoutant le mot clé ref et je ne veux pas envelopper le type de valeur avec une classe - ce qui fonctionnerait ...

(Bien sûr, je pourrais il suffit d'écrire une vieille boucle foreach pour le faire!)

Répondre

9

Vous modifiez simplement la variable locale - pas l'élément de la liste. Pour ce faire, vous voulez ConvertAll, ce qui crée une nouvelle liste/tableau:

int[] ints = new int[] { 1,2 }; 

    int[] newArr = Array.ConvertAll<int,int>(ints, AddTen); 

avec:

static int AddTen(int i) 
{ 
    return i+10; 
} 

Cela peut aussi être écrit avec une méthode anonyme:

int[] newArr = Array.ConvertAll<int,int>(ints, 
    delegate (int i) { return i+ 10;}); 

Ou en C# 3.0 en tant que lambda:

int[] newArr = Array.ConvertAll(ints, i=>i+10); 

autre que ... une boucle for:

for(int i = 0 ; i < arr.Length ; i++) { 
    arr[i] = AddTen(arr[i]); // or more directly... 
} 

Mais d'une manière ou d'une autre, vous allez devoir obtenir une valeur hors de votre méthode. Sauf si vous changez la signature, vous ne pouvez pas.

4

La méthode Array.ForEach() ne vous permet pas de modifier pratiquement ses membres. Vous pouvez le modifier en utilisant LINQ comme celui

ints = ints.Select(x => x +10).ToArray(); 
+0

En fait, Array.ConvertAll ferait dans ce cas (et est plus efficace que la longueur est calculée correctement), mais soit suffirait. –

+0

@ Marc, apprendre quelque chose de nouveau tous les jours. Je n'avais pas vu cette méthode auparavant. Merci! – JaredPar

0

foreach est la seule façon, les types de valeurs dans les tableaux et les listes sont toujours copiées et les modifier est donc pas aller travailler, à moins que vous stockez la valeur modifiée en arrière. La méthode AddTen ne le fait pas, elle modifie sa propre copie.

0

Tout d'abord, il est généralement dangereux de modifier la collection foreach. La plupart des collections maintiennent une "balise de version" interne pour garder trace des changements, de sorte que l'énumérateur lancera une exception lorsqu'il tentera d'itérer sur la collection modifiée.

En ce qui concerne votre question, il n'y a aucun moyen de le faire avec les types de valeurs et Array.ForEach. Utilisez ou Convert pour faire ce que vous voulez.

Questions connexes