C# - 作为方法参数传递的对象更改状态

C# - Object passed as method parameter changes state

我有一个 class 矩阵,其中包含值的二维数组 public 属性:

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

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

并且我在 Matrix 中将 *-Operator 作为静态方法重载:

    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;
    }

而且我在我的 main-class 中做了以下操作:

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 相同,如果是这样,这是好的和常见的做法吗?

我怀疑您的 Matrix 构造函数只是存储传入数组的值,而不是对其进行深度复制。在那种情况下,当数组被修改时,它会在两个实例中被修改。

众所周知,Matrix是引用类型,所以你新建了一个变量:

var resMatrix = new Matrix(m.Values);

但是,double[,]也是也是引用类型!当您这样做时:

Values = values;

您仍在使 Valuesvalues 相互依赖,即改变一个值会影响另一个。

为此,您需要创建一个副本。一种方法是 Clone:

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