c # en utilisant Array.ForEach action prédicats avec tableau de type de valeur ou chaîne
Question
Ai-je raison de penser l'extrait suivant ne fonctionne pas (les éléments du tableau ne sont pas modifiés) parce que le tableau est de type entier qui est le type de valeur.
class Program
{
public static void Main()
{
int[] ints = new int[] { 1,2 };
Array.ForEach(ints, new Action<int>(AddTen));
// ints is not modified
}
static void AddTen(int i)
{
i+=10;
}
}
serait de même si l'on utilise par exemple un tableau de chaînes, sans doute parce que la chaîne est immuable.
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 - qui fonctionnerait ...
(Bien sûr, je pourrais simplement écrire une vieille boucle foreach façonné le faire!)
La solution
Vous changez simplement la variable locale - pas l'élément dans 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 comme lambda:
int[] newArr = Array.ConvertAll(ints, i=>i+10);
Autre que cela ... une boucle de for
:
for(int i = 0 ; i < arr.Length ; i++) {
arr[i] = AddTen(arr[i]); // or more directly...
}
Mais d'une façon ou d'une autre, vous allez devoir obtenir une valeur sur de votre méthode. À moins que vous changez la signature, vous ne pouvez pas.
Autres conseils
La méthode Array.ForEach () ne vous laissera pas modifier pratiquement ses membres. Vous pouvez le modifier en utilisant LINQ comme celui-ci
ints = ints.Select(x => x +10 ).ToArray();
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 de retour la valeur modifiée. La méthode AddTen ne fait pas cela, il modifie sa propre copie.
Tout d'abord, il est généralement dangereux de modifier la collection vous foreach
ing plus. La plupart des collections maintiennent une balise « version » interne pour garder une trace des changements, donc recenseur jetteront une exception quand il attemt à itérer sur la collection modifiée.
Quant à votre question, il n'y a aucun moyen que vous pouvez le faire avec les types de valeurs et Array.ForEach
. Utilisez foreach
ou Convert
faire ce que vous voulez.