Il nocciolo del problema è qui:
Ci devo conservare questi valori in un altro array bidimensionale
Questo è in realtà imprecisa. Non stai creando un nuovo array; si imposta la variabile originalValues
su stesso matrice. Per una spiegazione più dettagliata, vedi sotto.
La confusione espresso nei commenti per Pieter's answer è dovuto a qualche incertezza che circonda il termine "copia completa".
Quando si tratta di copiare oggetti, c'è una copia profonda e una copia superficiale.
copia profonda consiste nel fare una copia di tutti i dati appartenenti a un oggetto, il che significa che se l'oggetto include componenti che sono essi stessi complessi (per esempio, esempi di tipi di riferimento definiti dall'utente), tali gli oggetti devono essere copiati in profondità (insieme a tutti gli membri e così via).
Shallow copia comporta semplicemente copiando tutti i campi da un oggetto all'altro, il che significa che se l'oggetto include tipi di riferimento, solo i riferimenti devono essere copiati (e quindi i riferimenti copiati verranno rivolte alla stessa oggetti).
Nel caso del codice che hai postato:
int[,] originalValues = this.Metrics;
... c'è in realtà non la copia di tutti gli oggetti a tutti. Tutto ciò che hai fatto è stato copiato un singolo riferimento, assegnando il valore di this.Metrics
(un riferimento) alla variabile originalValues
(anch'essa un riferimento, allo stesso array). Questo è essenzialmente lo stesso come un semplice assegnazione valore, in questo modo:
int x = y; // No objects being copied here.
Ora, il metodo Array.Clone
rende, di fatto, una superficiale copia . Ma come ha sottolineato Pieter, non c'è davvero alcuna differenza tra una copia "superficiale" o "profonda" di un array di numeri interi , poiché gli interi non sono oggetti complessi.
Se tu avessi qualcosa di simile:
StringBuilder[,] builders = GetStringBuilders();
StringBuilder[,] builderCopies = (StringBuilder[,])builders.Clone();
..., che ci si finisce con una nuova gamma (una copia, sì), ma uno che contiene tutti gli stessi oggetti StringBuilder
(quindi una copia superficiale). È qui che entra in gioco la copia profonda o poco profonda; se si desiderava un nuovo array contenente copie di copie da builders
, è necessario eseguire una copia profonda.
Nel caso qualcuno inciampare qui, ora c'e 'Array.Clone()'. (.net 4.5) – Jeevaka
@Jeevaka Questa domanda si riferisce in particolare alla creazione di una copia _deep_ di un array. Secondo [MSDN docs] (https://msdn.microsoft.com/en-us/library/system.array.clone (v = vs.110) .aspx), 'Array.Clone() '" Crea una ** copia ** superficiale della matrice. " (enfasi aggiunta). – jmbpiano
@ jmbpiano: Beh, se ho ragione :, 'int sono memorizzati per valore, non per riferimento. Quello che succederebbe qui è che Array.Clone() creerebbe un nuovo oggetto Array e copierà qualsiasi cosa nella memoria a cui fa riferimento il riferimento "this.Matrices". Poiché i contenuti dell'array non sono riferimenti, la nuova copia non condividerebbe nulla con l'originale. Se questi non fossero "int" ma qualcosa derivato da "oggetto", la tua argomentazione sarebbe corretta. Immagino che possiamo sempre provare e vedere. – Jeevaka