2013-05-21 13 views
6

Voglio cambiare il valore denaro nella mia lista, ma ottengo sempre un messaggio di errore:Non è possibile modificare la struttura in un elenco?

non può modificare il valore di ritorno di 'System.Collections.Generic.List.this [INT]' perché è non una variabile

Cosa c'è che non va? Come posso cambiare il valore?

struct AccountContainer 
{ 
    public string Name; 
    public int Age; 
    public int Children; 
    public int Money; 

    public AccountContainer(string name, int age, int children, int money) 
     : this() 
    { 
     this.Name = name; 
     this.Age = age; 
     this.Children = children; 
     this.Money = money; 
    } 
} 

List<AccountContainer> AccountList = new List<AccountContainer>(); 

AccountList.Add(new AccountContainer("Michael", 54, 3, 512913)); 
AccountList[0].Money = 547885; 

risposta

8

Hai dichiarato AccountContainer come struct. Così

AccountList.Add(new AccountContainer("Michael", 54, 3, 512913)); 

crea una nuova istanza di AccountContainer e aggiunge una copia di tale istanza alla lista; e

AccountList[0].Money = 547885; 

recupera una copia del primo elemento nell'elenco, cambia il campo della copia Money e scarta la copia – la prima voce della lista rimane invariato. Poiché questo non è chiaramente quello che intendevi, il compilatore ti avvisa di questo.

Soluzione: Non creare il mutevole struct s. Creare un struct immutabile (ad esempio, uno che non può essere modificato dopo che è stato creato) o creare un class.

9

Si sta utilizzando una struttura mutabile evil.

Trasformalo in una classe e tutto funzionerà correttamente.

+2

Peccato per "Punto", "Rettangolo" e "Dimensione". Almeno Microsoft ha imparato un po 'prima di creare 'Complesso'. Sarebbe stato molto fastidioso se * che * fosse mutabile. –

0

Probabilmente non raccomandato, ma si risolve il problema:

AccountList.RemoveAt(0); 
AccountList.Add(new AccountContainer("Michael", 54, 3, 547885)); 
+0

La rimozione del primo elemento in un elenco richiede lo spostamento di tutti gli elementi in un indice, quindi l'aggiunta dell'elemento richiederebbe il loro ripristino. Invece dovresti semplicemente impostare il valore su quell'indice: 'lista [indice] = nuovo ...;' – Servy

+0

Buon punto - Non ho provato a mantenere l'ordine delle liste. – bigtech

1

Ecco come vorrei risolverlo per lo scenario (utilizzando il immutabile metodo struct, piuttosto che cambiarlo con un class):

struct AccountContainer 
{ 
    private readonly string name; 
    private readonly int age; 
    private readonly int children; 
    private readonly int money; 

    public AccountContainer(string name, int age, int children, int money) 
     : this() 
    { 
     this.name = name; 
     this.age = age; 
     this.children = children; 
     this.money = money; 
    } 

    public string Name 
    { 
     get 
     { 
      return this.name; 
     } 
    } 

    public int Age 
    { 
     get 
     { 
      return this.age; 
     } 
    } 

    public int Children 
    { 
     get 
     { 
      return this.children; 
     } 
    } 

    public int Money 
    { 
     get 
     { 
      return this.money; 
     } 
    } 
} 

List<AccountContainer> AccountList = new List<AccountContainer>(); 

AccountList.Add(new AccountContainer("Michael", 54, 3, 512913)); 
AccountList[0] = new AccountContainer(
    AccountList[0].Name, 
    AccountList[0].Age, 
    AccountList[0].Children, 
    547885); 
+0

Ma 'AccountContainer' rappresenta semanticamente un valore? Dovrebbe essere una struttura? – Servy

+0

@Servy Questa è una domanda eccellente. Se l'esempio dato di cambiare 'Money' è un'operazione spesso eseguita, il' AccountContainer' verrebbe probabilmente pubblicato meglio come entità (in gergo DDD, cioè). Il mio istinto è che ciò che viene mostrato è un taglio più piccolo di un quadro più ampio in cui potrebbero esserci anche migliori opportunità per la scomposizione funzionale dei dati di entità contro valore. –

Problemi correlati