Contenitori .NET: quando sono i membri Per riferimento, Per valore?
-
06-07-2019 - |
Domanda
Eseguo la migrazione tra C ++ e VB.NET nelle mie iniziative di codifica ... che porta alla confusione occasionale su quando qualcosa è per valore o per riferimento in VB.NET.
Diciamo ad esempio che ho un array di MyObject che è popolato da un mucchio di oggetti.
dim MyArr(5000) of MyObject
Ora diciamo che le informazioni di questo array viaggiano attraverso varie strutture di dati:
dim MyList as new List(of MyObject)
for i as integer = 0 to 5000 step 1000
Mylist.add(MyArr(i))
next
poi
dim MyTable as new HashTable
dim i as integer = 0
for each O as MyObject in Mylist
if i mod 2 = 0 then
MyTable.add(O.ToString(), O)
end if
next
Nell'ambito dello scenario sopra, credo che tutto sia come riferimento. Se estraggo una voce da " MyTable " e modificare i membri MyObject, penso che l'originale in MyArr verrà modificato.
Tuttavia, mi sono imbattuto in situazioni in cui pensavo che qualcosa fosse per riferimento, ed era per valore.
Gli articoli vengono sempre aggiunti ai contenitori per riferimento o a volte vengono aggiunti per valore?
Sono confuso.
Soluzione
Non è un caso di " per riferimento " o " per valore " veramente. Il valore passato al metodo Aggiungi viene copiato. Tuttavia, per i tipi di riferimento quel valore è un riferimento a un oggetto - e se manipoli quell'oggetto tramite altri riferimenti ad esso, sarai in grado di vedere quelle modifiche comunque arrivi all'oggetto.
Se vedi mai copie indipendenti dei dati stessi, ciò suggerisce che stai utilizzando un tipo di valore ... ma se stai apportando modifiche , ciò suggerisce che stai utilizzando un mutable tipo di valore, che è una cattiva idea. I tipi di valore dovrebbero essere quasi sempre immutabili, altrimenti creano molta confusione. (Anche i tipi di riferimento possono essere immutabili - string è un buon esempio.)
Per ulteriori informazioni sui tipi di riferimento e sui tipi di valore, vedere i miei articoli su riferimenti e parametri . Sono scritti da una prospettiva C #, ma i fondamenti si applicano anche a VB.
Penso che una volta che avrai compreso la distinzione tra un valore di tipo valore e un riferimento, le raccolte avranno più senso per te.
Altri suggerimenti
È possibile utilizzare questa regola: se è possibile assegnare null in oggetto, verrà passato per riferimento. Altrimenti verrà passato per valore.
Eccezione a questa regola sono tipi e strutture nullabili. Vengono sempre passati per valore.
Penso che dipenda dal tipo di elementi. Non sulle collezioni.
per esempio:.
int [] ints = new int [10];
ints [0] = 1; // -)
in questo caso 1 verrà copiato purché sia ??ValueType.