我有一个带有2d数组值的类作为公共属性:
public class Matrix
{
public double[,] Values { get; set; }
public Matrix(double[,] values)
{
Values = values;
}
...
}
我将* -Operator重载为Matrix中的静态方法:
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按预期更改。但是m1在乘法后获得与m2相同的值。我知道引用类型作为引用传递给方法,但我在堆上分配了一个新对象,调用“var resMatrix = new Matrix(m.Values);”对?或者编译器是否将这两个对象合并为一个以进行性能优化?是否有可能像价值类型一样保持m1相同,如果是这样,它是否是常见的做法?
答案 0 :(得分:2)
如您所知,Matrix
是引用类型,因此您创建了一个新变量:
var resMatrix = new Matrix(m.Values);
但是,double[,]
也是引用类型!当你这样做时:
Values = values;
你仍然使Values
和values
相互依赖,即改变一个人的价值会影响另一个。
为此,您需要创建副本。一种方法是Clone
:
Values = values.Clone() as double[,];
答案 1 :(得分:0)
我怀疑你的Matrix构造函数只是存储传入的数组的值,而不是制作它的深层副本。在这种情况下,当修改数组时,它将在两个实例中被修改。