如何在 C# 中按值而不是按引用复制对象

How do I copy an object by value instead of by reference in C#

我正在用 C# 编写一个简单的 hillclimber 算法并正在尝试以下方法:

获取初始解决方案
将解决方案复制到新对象
应用算法复制
比较初始解的obj值和copy
的obj值 如果更好 - 复制回初始解决方案。

我知道这个主题在之前的 post 中已经被触及,并尝试实施那里的建议 - 使用 IClonable class。这是我试过的:

我的解决方案Class:

class Solution : ICloneable
{

    public Dictionary<Room, List<Patient>> solution { get; set; }


    public Solution()
    {
        solution = new Dictionary<Room, List<Patient>>();

    }
    public object Clone()
    {
        return this.MemberwiseClone();
    }
}

算法:

public static void swap (Solution solution, Output input, Random rand)
    {


        Solution intSoln = new Solution();
        intSoln = (Solution)solution.Clone();

//Moving things around in intSoln here

        Console.WriteLine("new solution = " + objValue(intSoln, input));
        Console.WriteLine("old solution = " + objValue(solution, input));
        if (objValue(intSoln, input) < objValue(solution, input))
        {
            solution = (Solution)intSoln.Clone();
        }
    }

查看新旧解决方案的打印输出,它们总是相同的,这意味着代码显然仍然是通过引用复制的。我很困惑,不知道该怎么办。任何帮助将不胜感激。

您需要对解决方案类型进行深度克隆。所以实现 ICloneable 接口:

public class Solution : ICloneable
{
  public object Clone()
  {
    // creating a new dictionnary
  }
}

MemberwiseClone 将执行 浅拷贝,这意味着您将获得一个新实例,其字段具有与初始对象相同的引用。

您想改为进行深度复制。这是一个更上一层楼的副本:

public object Clone()
{
    var copy = new Solution();

    foreach (var pair in solution)
        copy.solution.Add(pair.Key, pair.Value);

    return copy;
}

这将复制字典,但它的键和值将指向相同的实例。所以你可以用类似的东西执行更深的复制:

public object Clone()
{
    var copy = new Solution();

    foreach (var pair in solution)
        copy.solution.Add(new Room(pair.Key), pair.Value.ToList());

    return copy;
}

或:

public object Clone()
{
    var copy = new Solution();

    foreach (var pair in solution)
        copy.solution.Add(new Room(pair.Key), pair.Value.Select(i => new Patient(i)).ToList());

    return copy;
}

您需要为 RoomPatient 编写一些复制构造函数。希望你明白了。