Pergunta

Eu tenho esse código (C #):

using System.Collections.Generic;

namespace ConsoleApplication1
{
    public struct Thing
    {
        public string Name;
    }

    class Program
    {
        static void Main(string[] args)
        {
            List<Thing> things = new List<Thing>();
            foreach (Thing t in things) //  for each file
            {
                t.Name = "xxx";
            }
        }
    }
}

Ele não irá compilar.
O erro é:

Cannot modify members of 't' because it is a 'foreach iteration variable'

Se eu mudar Thing a um class em vez de um struct, no entanto, ele faz compilação.

Por favor, alguém pode explicar o que está acontecendo?

Foi útil?

Solução

Mais ou menos o que diz, o compilador não permitem alterar (partes) do var looping em um foreach.

Basta usar:

for(int i = 0; i < things.Count; i+= 1) //  for each file
{
    things[i].Name = "xxx";
}

E funciona quando Thing é uma classe, porque então o seu var looping é uma referência, e você só fazer alterações no objeto referenciado, não para a própria referência.

Outras dicas

A struct há nenhum tipo de referência, mas um tipo de valor.

Se você teria um class em vez de um struct para Thing, o loop foreach criaria uma variável de referência para você, que apontaria para o elemento correto em que você lista. Mas uma vez que é um tipo de valor, ele só funciona com uma cópia do seu Thing, que é, neste caso, a variável de iteração.

A struct é um tipo de valor, mas uma classe é um tipo de referência. É por isso que compila quando Esta é uma classe, mas não quando é uma struct

Veja mais: http://www.albahari.com/valuevsreftypes.aspx

Uma sintaxe alternativa que prefiro @ solução de Henk é isso.

DateTime[] dates = new DateTime[10];

foreach(int index in Enumerable.Range(0, dates.Length))
{
   ref DateTime date = ref dates[index];

   // Do stuff with date.
   // ...
}

Se você não está fazendo uma quantidade razoável de trabalho no circuito, em seguida, ter de repetir a indexação em todos os lugares é mais fácil no olho imo.

P.S. DateTime é realmente um exemplo realmente pobre como ele não tem quaisquer propriedades que você pode definir, mas você começa a foto.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top