如果我正在处理它的副本,为什么原始值会发生变化?

Kha*_*laf -1 c# wpf logic list

我正在使用这个例程将一些坐标加载到容器中,绘制它们,放大它们以及这些任务.然后在按钮单击时,我倾向于将所有内容重置为原始状态或初始状态.要做到这一点,我拿一份初始版本并播放副本.但是在重置按钮单击时,我销毁副本,获取初始副本并处理它.等等.

出于某种原因,更改副本时原始容器会更改.谁能发现我做错了什么?

按顺序,我先加载数据并复制一份:

//          CoordPoint is a simple xy point 
public List<CoordPoint> MyLoadedCoords { get { return myLoadedCoords; } set { myLoadedCoords = value; }}
public List<CoordPoint> MyDisplayedCoords { get { return myDisplayedCoords; } set { myDisplayedCoords = value }}

private List<CoordPoint> myLoadedCoords;
private List<CoordPoint> myDisplayedCoords;

//..

public void LoadData()
    {
        // load points from file
        MyLoadedCoords = File.ReadLines("C:\\...\\Samples.txt") 

        // get a copy of original coords
        MyDisplayedCoords = MyLoadedCoords.ToList();
    }
Run Code Online (Sandbox Code Playgroud)

请注意,此处代码中MyLoadedCoords存在任何位置(并且在Reset函数中,向下).然后我处理副本MyDisplayedCoords几个类似的地方:

public void UpdateDisplayPosition()
{
    for (var i = 0; i < MyDisplayedCoords.Count; i++)
    {  
        MyDisplayedCoords[i].X += XCoordOffset; //some processed values
        MyDisplayedCoords[i].Y += YCoordOffset; //some processed values
    }
}
Run Code Online (Sandbox Code Playgroud)

重置按钮我这样做:

public void ResetZoom()
{
    MyDisplayedCoords = MyLoadedCoords.ToList(); // I set break point here
    AdjustInitialDisplayPosition();
    DrawImage();
}
Run Code Online (Sandbox Code Playgroud)

ResetZoom()没有做到预期的,当我调试和打破时, MyDisplayedCoords = MyLoadedCoords;我看到它MyLoadedCoords包含完全相同的值/对象MyDisplayedCoords

编辑:

我实现了IClonable与"overrided的" Clone()在我班上的功能,但它没有工作:

public class CoordPoint : ICloneable
{
    // .. 

    public object Clone()
    {
        return new CoordPoint {X = X, Y = Y, Z = Z, Color = Color};
    }
}
Run Code Online (Sandbox Code Playgroud)

然而,没有IClonable,这个"复制"就像HB回答克隆一样工作:

MyDisplayedCoords = MyLoadedCoords.Select(c => new CoordPoint { X = c.X, Y = c.Y, Z = c.Z, Color = c.Color }).ToList();
Run Code Online (Sandbox Code Playgroud)

H.B*_*.B. 5

MyDisplayedCoords = MyLoadedCoords 不复制任何东西,它将对同一对象的引用分配给属性,现在两个属性都指向同一个对象.

要复制可以使用Linq方法的列表(它总是返回一个新列表):

MyDisplayedCoords = MyLoadedCoords.ToList();
Run Code Online (Sandbox Code Playgroud)

要进行深层复制,您可以执行类似的操作,然后列表中的实例也会有所不同:

MyDisplayedCoords = MyLoadedCoords.Select(c =>
                                       new CoordPoint { X = c.X, Y = c.Y }).ToList();
Run Code Online (Sandbox Code Playgroud)