2017-07-02 12 views
0

変更:C#がメソッドのパラメータとして渡されたオブジェクトは、私は公共の財産としての値の2Dアレイを持つクラスのMatrixを持っている状態

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);"という呼び出しでヒープ上に新しいオブジェクトを割り当てました。右?または、コンパイラはパフォーマンス最適化のためにそれら2つのオブジェクトを1つにマージしますか? m1を値の型と同じように保つ可能性はありますか?もしそうなら、それは良いと一般的な慣行ですか?

答えて

2

ご存知のように、Matrixは参照型であるので、あなたは、新しい変数製:

var resMatrix = new Matrix(m.Values); 

しかし、double[,]参照型です!あなたがこれを行うとき:

Values = values; 

をあなたはまだ他に影響を与えます、すなわち1の値を変更Valuesvalues相互に依存をしています。

これを行うには、コピーを作成する必要があります。これを行う方法の1つは、Cloneです:

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

あなたのMatrixコンストラクタは、渡された配列の値を格納しているだけで、それを深くコピーしているとは思えません。その場合、配列が変更されると、配列は両方のインスタンスで変更されます。

+0

はい、それは正しいです、私は私の質問のコード例に私のコンストラクタを追加します。ディープコピーの作成方法に関するご提案はありますか?そして、なぜこれがコンストラクタで発生する必要がありますか? –

関連する問題