在 C# 中使用 ICloneable 接口进行深度复制的问题
Problem with making a deepcopy using IClonable interface in C#
我在制作对象的深拷贝时遇到问题。
我需要深拷贝 Graph class 对象。
这是我的 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;
}
}
到目前为止,我已经尝试过:
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
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);
}
由于您的节点是 int
,这是一种值类型,您可以考虑制作 Graph
class immutable。不可变类型永远不需要克隆,这可以使代码更容易理解。
这应该有效
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;
}
我在制作对象的深拷贝时遇到问题。
我需要深拷贝 Graph class 对象。
这是我的 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;
}
}
到目前为止,我已经尝试过:
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
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);
}
由于您的节点是 int
,这是一种值类型,您可以考虑制作 Graph
class immutable。不可变类型永远不需要克隆,这可以使代码更容易理解。
这应该有效
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;
}