2009-10-23 131 views
1

我正在使用一個名爲BigNumDesc的類來表示一個數字。我有一組鋸齒數字,代表一個矩陣。 我首先聲明這個矩陣的方式如下:深拷貝參考類型

BigNumDec[][] matrix = new BigNumDec[][] { 
     new BigNumDec[] { 1, 2 }, 
     new BigNumDec[] { 3, 4 } 
    }; 

現在,我有這樣的方法,我想打電話:

static BigNumDec[][] GetStrictlyUpperTriangle(BigNumDec[][] matrix) 
{ 
    BigNumDec[][] newMatrix = new BigNumDec[matrix.Length][]; 
    matrix.CopyTo(newMatrix, 0); 
    return null; 
} 

我在最後一行一個突破點。如果在監視窗口中,我接受任何矩陣項目並對其進行更改,它將會改變太新的矩陣,因爲所有BigNumDec都是參考類型(來自其創建者的糟糕設計決策?)。我怎樣才能做到這一點?我需要對newMatrix進行修改,所以我必須首先從矩陣中複製它。

編輯:現在嘗試使用整數,但它發生的是一樣的。我會不會發生值類型?

BigNumDec是不可變的。

回答

3

其值類型仍在發生的原因是因爲您使用的是數組數組。你很淺 - 複製「外部」數組,它只是將引用複製到兩個「內部」數組中。

您還沒有表現出BigNumDec是否是不可改變與否(我希望如此),但如果是這樣,你應該罰款,如果你只是在陣列深層複製。或者,您可以使用矩形陣列[,]而不是鋸齒陣列[][]?如果是這樣,一個簡單的副本就足夠了。對矩形陣列有性能影響,請介意 - 值得測試一下,看看它是否會對您造成問題。你會得到更好的參考位置,但實際的數組訪問速度並不快。

+0

一個簡單的它適用於整數。它能與BigNumDec一起使用嗎?我會說不。 – 2009-10-23 07:35:30

+0

它似乎工作。現在我很困惑。 – 2009-10-23 07:36:27

+0

你能否解釋一下,爲什麼不可改變或者不會在這裏有所作爲?當它檢測到我想改變它的值時,它是否會在幕後創建一個新的? – 2009-10-23 07:39:13

1

問題出在您初始化BigNumDec數組時,您正在創建一個BigNumDec對象的一維數組。 [0] = {1,2},[1] = {3.4}。然後,您就有效地複製了這些對象的引用,而不是它們的內容,因此這些值繼續發生變化。

你的初始化更改爲:

BigNumDec[,] matrix = new BigNumDec[,] { 
    { 1, 2 }, 
    { 3, 4 } 
}; 
1

如果你的對象是可序列可以使用序列化實現深拷貝。這不是非常有效(按性能),但很簡單。

public BigNumDec[][] CopyUsingSerialization(BigNumDec[][] original) 
{ 
    var binaryFormatter = new BinaryFormatter(); 
    var serializationStream = new MemoryStream(); 
    binaryFormatter.Serialize(serializationStream, original); 
    serializationStream.Position = 0; 
    var copy = (BigNumDec[][])binaryFormatter.Deserialize(serializationStream); 
    return copy; 
} 

您必須聲明BigNumDec爲[Serializable接口]:

[Serializable] 
public class BigNumDec 
{ 
    //class content 
} 

(在其他的答案在這裏說,如果你能移動到二維數組,而不是鋸齒狀你會得到更好的解決方案)