2011-08-19 5 views
14

Ho una struttura definita dall'utente in un elenco che sto cercando di modificare il valore di in un singolo elemento all'interno dell'elenco di strutture. L'accesso all'elemento non è un problema. Tuttavia, quando provo ad aggiornare il valore, il compilatore segnala:Come si assegnano i valori agli elementi della struttura in un elenco in VB.NET?

"espressione è un valore e quindi non può essere bersaglio di assegnazione "

Ad esempio:

Public Structure Person 

    Dim first as String 
    Dim last as String 
    Dim age as Integer 

End Structure 

_

Public Sub ListTest() 

    Dim newPerson as Person 

    Dim records as List (Of Person) 
    records = new List (Of Person) 

    person.first = "Yogi" 
    person.last = "bear" 
    person.age = 35 

    records.Add(person) 
    records(0).first = "Papa" ' <<== Causes the error 
End Sub 
+9

Ogni programmatore .NET commette questo errore una volta. Una struttura è un tipo di valore, i record (0) restituiscono una * copia *. L'aggiornamento del "primo" membro della copia non porta a nulla. La persona deve essere una classe. –

+0

Presupposti di carry-over da C++;). Grazie per il consiglio. –

+0

@Hans: sì, è facile dimenticare che anche 'records (0)' restituirà una copia della struct ... – IAbstract

risposta

13

Come gli altri commenti s aiuto, quando si fa riferimento a record (0), si ottiene una copia della struct poiché si tratta di un tipo di valore. Cosa si può fare (se non si può cambiare ad una classe) è qualcosa di simile:

Dim p As Person = records(0) 
p.first = "Papa" 
records(0) = p 

Anche se, penso che è solo più facile da usare una classe.

+0

Ho appena trovato questo problema perché avevo un dizionario con il valore di una struttura piuttosto che di una classe. Grazie per la soluzione semplice !! – DontFretBrett

+0

Il problema con questo è che copia l'intera struttura anziché solo il puntatore ad esso. Ecco perché devi copiarlo. Doppio smacco. Un sacco di spese generali. – Brain2000

+0

@ Brain2000: concordato, ma quando si utilizzano i tipi di valore, non si ha molta scelta. 'Persona' avrebbe dovuto essere una classe non solo per questo motivo, ma anche perché le strutture mutabili sono scoraggiate. –

4

Ci sono in realtà due concetti importanti da ricordare qui.

La prima è che, come Hans e Chris hanno sottolineato, Structure Person dichiara un tipo di valore dei quali sono passati copie tra chiamate di metodo.

È comunque possibile accedere (ad esempio, ottenere e set) ai membri di un tipo di valore. Dopo tutto, questo opere:

Dim people(0) As Person 
people(0).first = "Yogi" 
people(0).last = "Bear" 
people(0).age = 35 

Così l'altro punto importante da capire è che records(0) accede speciale Itemproprietà della classe List(Of Person), che è un wrapper zuccherino intorno a due chiamate di metodo (un getter e setter). È non un accesso diretto all'array; se lo fosse (ad esempio, se records fosse un array), il codice originale avrebbe effettivamente funzionato.

1

Ho avuto lo stesso problema e l'ho risolto aggiungendo un sub semplice alla struttura che modifica il valore della proprietà.

Public Structure Person 

Dim first as String 
Dim last as String 
Dim age as Integer 

Public Sub ChangeFirst(value as String) 
    me.first = value 
End Sub 

End Structure 
Problemi correlati