2017-07-02 203 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

是的,这是正确的,我会将我的构造函数添加到我的问题的代码示例中。您对如何创建深度复制有任何建议吗?为什么这需要在构造函数中发生? –