c # en utilisant Array.ForEach action prédicats avec tableau de type de valeur ou chaîne

StackOverflow https://stackoverflow.com/questions/561170

  •  05-09-2019
  •  | 
  •  

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!)

Était-ce utile?

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 foreaching 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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top