Pregunta

Estoy en lo correcto al pensar el siguiente fragmento no funciona (los elementos de matriz no se modifican) ya es la matriz de número entero que es el tipo de valor.

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;
    }
}

Lo mismo ocurriría si el ejemplo utiliza una matriz de cadena, presumiblemente debido a que la cadena es inmutable.

La pregunta que tengo es: -

¿Hay una manera de evitar esto? No puedo cambiar la firma del método de devolución de llamada - por ejemplo mediante la adición de la palabra clave ref y no quiero envolver el tipo de valor con una clase - que trabajaría ...

(Por supuesto, yo podría simplemente escribir un viejo bucle foreach moda para hacer esto!)

¿Fue útil?

Solución

Usted es simplemente cambiando la variable local - no es el elemento de la lista. Para ello, desea ConvertAll, lo que crea una nueva lista / matriz:

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

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

por:

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

Esto también se puede escribir con un método anónimo:

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

O en C # 3.0 como lambda:

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

Aparte de eso ... un bucle for:

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

Pero de una manera u otra, van a tener que conseguir un valor a cabo de su método. A menos que cambie la firma, no se puede.

Otros consejos

El método Array.ForEach () no le permite modificar prácticamente a sus miembros. Se puede modificar mediante el uso de LINQ como este

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

foreach es la única manera, los tipos de valor en las matrices y listas siempre se copian y su modificación por lo tanto no va a funcionar, a menos que se almacena el valor modificado espalda. El método AddTen no está haciendo eso, se modifica su propia copia.

En primer lugar, por lo general es peligroso para modificar la colección que estés foreaching terminado. La mayoría de las colecciones mantienen una "etiqueta de versión" interno para realizar un seguimiento de los cambios, por lo que se empadronador una excepción cuando se attemt para iterar sobre la colección modificada.

En cuanto a su pregunta, no hay manera de que pueda hacer eso con los tipos de valores y Array.ForEach. Utilice foreach o Convert a hacer lo que quiera.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top