0

我在制作对象的深层副本时遇到了麻烦。

我需要制作 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循环添加所有元素edgesvertices但该解决方案非常慢。

4

2 回答 2

1

欢迎来到 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,这是一种值类型,您可以考虑使Graphimmutable。永远不需要克隆不可变类型,这可以使代码更容易理解。

于 2020-11-14T17:16:04.760 回答
1

这应该工作

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;
}
于 2020-11-14T17:25:49.420 回答