【发布时间】:2011-01-20 06:31:07
【问题描述】:
我正在使用 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 是具有多种原始(双精度)和非原始(向量)数据类型的点的实例。
我遇到了一个(明显的)问题,上面的代码很可能只是将 StartPoint 设置为指向以前是 EndPoint 的数据,而 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
}
【问题讨论】:
-
我假设 Point 是一个类,而不是一个结构?如果它的所有成员都是值类型,您是否考虑过将其也设为值类型?
-
@Bubbafat:我还有一些其他类只包含原语和 Vector(由原语组成)。如果我将所述类转换为 struct 以及 Vector,这是否允许我执行简单的深层复制而不是简单地使两个对象指向同一内存的分配?
-
复制值类型总是会创建值类型的副本(与仅复制引用的引用类型相反)。在复制所有内容之前,您需要考虑这样做的其他影响(性能、装箱、内存、堆栈使用等),但如果这些类型是逻辑值类型而不是引用类型。