我在制作对象的深度副本时遇到了麻烦。
我需要制作Graph类对象的深度副本。这是我的Graph
类和Edge
类,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;
}
}
到目前为止,我已经尝试过:
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;
}
但它只是创建了一个肤浅的副本,并没有起到作用。当然,IClonable
接口是为上述所有示例实现的。我试着在网上查找其他例子,但没有结果。我使用foreach
循环将edges
和vertices
中的所有元素相加,但该解决方案非常缓慢。
欢迎来到OOP的乐趣!
撇开玩笑不谈,在构建克隆时,您将需要创建新的List
对象:
public Graph(Graph other)
{
this.edges = new List<int>(other.edges);
this.vertices = new List<int>(other.vertices);
}
您的Clone
代码将保持不变:
public Graph Clone() {
return new Graph(this);
}
object ICloneable.Clone()
{
return Clone();
}
如果你的Edge
类是可变的,那么你也需要克隆它们:
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);
}
由于您的节点是int
,这是一种值类型,因此您可以考虑使Graph
类不可变。不可变类型永远不需要克隆,这可以使代码更容易理解。
这应该能在中工作
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;
}