1

私はC#でいくつかのシミュレーションコードに取り組んでおり、次の行に沿っていくつかのコードがあります。

public void predict(Point start, Point end)
{
    end.velocity = start.velocity + dt * end.acceleration;
    end.position = start.position + dt * end.velocity;
}

ここで、位置、速度、加速度は、関連する演算子で定義したいくつかのベクトルデータ型です。

私がやっているコードと同様に:

StartPoint = EndPoint;
EndPoint = CurrentPoint;

* Pointsは、いくつかのプリミティブ(double)および非プリミティブ(Vector)データ型を持つPointsのインスタンスです。

上記のコードは、以前はEndPointであったデータを指すようにStartPointを設定するだけで、EndPointはCurrentPointを指すようになるという(明らかな)問題が発生しています。

つまり、CurrentPointを再度変更すると、誤ってEndPointを変更してしまうことになります。

C ++では、Pointオブジェクト内の基になるデータのディープコピーを実行するように代入演算子を定義できるため、これを簡単に防ぐことができます。C#でこれを防ぐにはどうすればよいですか?

助けてくれてありがとう!

編集:Vectorクラスは次のように定義されます

[Serializable]
public class Vector
{
    private Double[] data = new Double[Constants.Dimensions];

    ... snip ...

    public static Vector operator +(Vector lhs, Vector rhs)
    {
        Vector result = new Vector();
        for (UInt32 i = 0; i < Constants.dimensions; i++)
            result[i] = lhs[i] + rhs[i];
        return result;
    }

    lots more code here 
}
4

3 に答える 3

2

これは、C#デザインのIMHOで最も厄介な問題の1つです。

'Point'が構造体(値)の場合、メンバーごとのコピーが作成されるためx = y、yの独立したコピーが作成されます。ただし、それがクラス(参照)の場合x = y、参照xがyに使用される同じストレージを指すようになるため、2つは同じデータに対して異なる「エイリアス」になります。

あなたの問題について私が知っている2つの解決策は次のとおりです。

  • 構造体を使用します。これにより、数学のクラスに期待する値型の動作が得られます。コードを効率的に保つために、構造体が継続的にコピーされるのを避けるために、どこでも参照を渡す必要があるかもしれません。

  • クラスを使用しますが、=を使用するときは、データの独立したコピーを保持するように非常に注意してください。x = yたとえば、別のものに変更する必要がありますx = new Point(y);

于 2011-01-20T07:13:40.380 に答える
0

Clone()を使用して、必要な方法でディープコピーを実装できますか?

StartPoint = EndPoint; 
EndPoint = (Point)CurrentPoint.Clone(); 
于 2011-01-20T06:45:00.503 に答える
0

参照で渡したい。メソッドは現在値を渡しています。つまり、変数の値がコピーされています。メソッドは常にデータのコピーを処理します。

参照で渡すには、次のようにします。

public void predict(ref Point start, ref Point end)
{
    end.velocity = start.velocity + dt * end.acceleration;
    end.position = start.position + dt * end.velocity;
}

次に、次のようにrefキーワードを使用してメソッドを呼び出す必要があります。

predict(ref start, ref end);
于 2011-01-20T06:51:35.523 に答える