2017-07-02 224 views
0

我有一個類矩陣與值的二維陣列作爲公共屬性:C# - 作爲方法參數傳遞的對象改變狀態

public class Matrix 
{ 
    public double[,] Values { get; set; } 

    public Matrix(double[,] values) 
    { 
     Values = values; 
    } 
    ... 
} 

我重載* - 運算符作爲基質內部的靜態方法:

public static Matrix operator *(Matrix m, double operand) 
    { 
     var resMatrix = new Matrix(m.Values); 
     for (var i = 0; i < resMatrix.Values.GetLength(0); i++) 
     { 
      for (var j = 0; j < resMatrix.Values.GetLength(1); j++) 
      { 
       resMatrix[i, j] *= operand; 
      } 
     } 
     return resMatrix; 
    } 

而且我也按照我的主類:

internal class Program 
{ 
    public static void Main(string[] args) 
    { 
     var m1 = new Matrix(new double[,] 
     { 
      {1, 2, 3}, 
      {4, 5, 6}, 
      {7, 8, 9} 
     }); 
     Console.WriteLine(m1); 

     var m2 = m1 * 2; 

     Console.WriteLine(m2); 
     Console.WriteLine(m1); 
    } 
} 

運營商本身工作正常,M2是改變我ntended。但是在乘法之後,m1會獲得與m2相同的值。我知道引用類型是作爲引用傳遞給方法的,但我在堆上分配了一個新對象,其中調用了「var resMatrix = new Matrix(m.Values);」對?還是編譯器將這兩個對象合併爲一個用於性能優化?是否有可能像價值類型一樣保持m1不變?如果是這樣,這是否是一種好習慣?

回答

2

如你所知,Matrix是引用類型,所以你做了一個新的變量:

var resMatrix = new Matrix(m.Values); 

然而,double[,]引用類型!當你這樣做:

Values = values; 

你還在做Valuesvalues互相依賴的,即改變一個人的價值會影響其他。

爲此,您需要創建一個副本。一種方法是Clone

Values = values.Clone() as double[,]; 
0

我懷疑你的矩陣構造函數只是存儲傳入數組的值,而不是對它進行深層複製。在這種情況下,當數組被修改時,它將在兩個實例中被修改。

+0

是的,這是正確的,我會將我的構造函數添加到我的問題的代碼示例中。您對如何創建深度複製有任何建議嗎?爲什麼這需要在構造函數中發生? –