如何在 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;
}
您需要为 Room
和 Patient
编写一些复制构造函数。希望你明白了。
我正在用 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;
}
您需要为 Room
和 Patient
编写一些复制构造函数。希望你明白了。