简体   繁体   English

在 C# 中使用 IClonable 接口进行深层复制的问题

[英]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循环添加edgesvertices的所有元素,但该解决方案非常慢。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM