【问题标题】:Multiplication operator overload modifying original variable (C#)?乘法运算符重载修改原始变量(C#)?
【发布时间】:2013-07-21 05:00:20
【问题描述】:

我正在开发一个矩阵库作为一个学习项目,在此过程中,我重载了 * 运算符来执行矩阵乘法。我还重载了它以处理标量乘法(将矩阵的每个元素乘以双精度)。我的问题是,当运行以下代码时, test2 和 test 都被修改了,这是不希望的。

Matrix test2 = 2 * test;

我确定这是一个问题,因为 Matrix 是一个类,因此是通过引用传递的,但没有将 Matrix 更改为结构(我认为这不合适,并且尝试时不会'似乎不起作用),我看不到任何解决此问题的方法。我该如何解决这个问题?

实际操作符代码是

public static Matrix operator *(Matrix m1, double c)
{
   Matrix ret = m1;

   for (long i = 0; i < ret.Width; i++) // Iterate over the rows.
    {
        for (long p = 0; p < ret.Height; p++) // Iterate over the columns.
        {
            ret[i, p] *= c;
        }
    }

   return ret;
}

【问题讨论】:

    标签: c# types reference operators


    【解决方案1】:

    您不应使用代码修改现有矩阵。签名 screams 表明它正在创建一个 new Matrix 并返回它。

    我不确定您的复制方法/构造函数是什么,但不要m1 分配给ret;您应该制作m1副本,修改副本,并返回副本,留下m1 不变。

    public static Matrix operator *(Matrix m1, double c)
    {
        Matrix ret = m1.Clone(); //not sure what your "copy" method is
    
        //do the multiplication on ret
    
        return ret;
    }
    

    【讨论】:

    • 我现在已经创建了一个方法来执行此操作,但是有什么方法可以避免每次需要复制值时调用 xxxx.Clone() ? IE。当使用 ret = m1;相当于 ret = m1.Clone();
    • 唯一的方法是将您的Matrix 实现为值类型struct。不过,这可能会对您当前使用该类型的方式产生影响。 (谷歌“可变结构是邪恶的”)
    【解决方案2】:

    由于Matrix 是一个引用类型,ret = m1 不会复制您的输入参数并且您最终会对其进行修改。

    此问题的正确解决方案是制作m1 的深层副本并对其进行修改。比如:

    Matrix ret = m1.MakeCopy(); // you need to define this
    
    // and now you are free to modify ret as much as you like
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多