[英]Problem with making a deepcopy using IClonable interface in C#
I'm having a trouble of making a deep copy of an object.我在制作 object 的深拷贝时遇到了麻烦。
I need to make a deep copy of Graph class object. This is my Graph
class and Edge
class from which Graph
is using objects.我需要对 Graph class object 进行深度复制。这是我的
Graph
class 和Edge
class, Graph
从中使用对象。
class Graph : ICloneable
{
private List<Edge> edges;
private List<int> vertices;
public Graph()
{
edges = new List<Edge>();
vertices = new List<int>();
}
public List<Edge> Edges
{
get
{
return edges;
}
}
public List<int> Vertices
{
get
{
return vertices;
}
}
}
class Edge
{
public int vertexV;
public int vertexU;
public int weigth;
public Edge(int vertexV, int vertexU, int weigth)
{
this.vertexV = vertexV;
this.vertexU = vertexU;
this.weigth = weigth;
}
}
So far, I have tried:到目前为止,我已经尝试过:
public Graph Clone() { return new Graph(this); }
object ICloneable.Clone()
{
return Clone();
}
public Graph(Graph other)
{
this.edges = other.edges;
this.vertices = other.vertices;
}
public object Clone()
{
var clone = (Graph)this.MemberwiseClone();
return clone;
}
But it only created a shallow copy which doesn't do the trick.但它只创建了一个浅表副本,无法解决问题。 Of course,
IClonable
interface was implemented for all examples above.当然,上面所有的例子都实现了
IClonable
接口。 I tried looking on other examples online but with no results.我尝试在网上查看其他示例,但没有结果。 I was using
foreach
loop the add all the elements from edges
and vertices
but that solution is extremely slow.我正在使用
foreach
循环添加edges
和vertices
的所有元素,但该解决方案非常慢。
Welcome to the joys of OOP!欢迎来到 OOP 的乐趣!
Joking aside, you will need to create new List
objects when you construct the clone:开个玩笑,当你构造克隆时,你需要创建新的
List
对象:
public Graph(Graph other)
{
this.edges = new List<int>(other.edges);
this.vertices = new List<int>(other.vertices);
}
Your Clone
code would then be unchanged:您的
Clone
代码将保持不变:
public Graph Clone() {
return new Graph(this);
}
object ICloneable.Clone()
{
return Clone();
}
If your Edge
class is mutable then you will need to clone those too:如果您的
Edge
class 是可变的,那么您也需要克隆它们:
public Graph(Graph other)
{
this.edges = other.edges.Select(e => new Edge(e.vertexV, e.vertexU, e.weight)).ToList();
this.vertices = new List<int>(other.vertices);
}
Since your nodes are int
, which is a value-type, you might consider making the Graph
class immutable .由于您的节点是
int
,这是一种值类型,您可以考虑使Graph
class 不可变。 Immutable types never need to be cloned, which can make code much easier to understand.不可变类型永远不需要克隆,这可以使代码更容易理解。
This should work这应该工作
public object Clone()
{
Graph graph = new Graph();
edges.ForEach(e => graph.edges.Add(new Edge(e.vertexV, e.vertexU, e.weigth)));
graph.vertices.AddRange(vertices.ToArray());
return graph;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.