【发布时间】:2016-06-21 05:07:54
【问题描述】:
假设我有以下课程:
public class Author
{
public int ID {get; private set;}
public string firstName {get; private set;}
public string lastName {get; private set; }
public Author(int id, string firstname, string lastname)
{
this.ID = ID;
this.firstName = firstname;
this.lastName = lastName;
}
public static Author Clone(Author clone)
{
Author copyAuth = new Author(clone.ID, clone.firstName, clone.lastName);
return copyAuth;
}
}
和
public class Book
{
public string bookTitle {get; private set;}
private List<Author> authors;
private List<Author> copyofAuthors;
public string ISBN {get; private set; }
public Book(string bookTitle, List<Author> authors, string ISBN)
{
copyofAuthors = new List<Author>();
this.bookTitle = bookTitle;
this.ISBN = ISBN;
//How do I create a deep copy of my authors List?
foreach(Author copy in authors)
{
Author addAuthors = Author.Clone(copy);
copyofAuthors.Add(addAuthors);
}
}
}
如何创建List<Authors> 集合的深层副本?我已经阅读了 StackOverFlow 上建议序列化的其他页面,以及我不熟悉且似乎令人困惑的建议。
我跟随this link 创建了我的克隆方法。
问题 1:
上述实现是否被视为深层复制?如果是这样,这样做可以吗?我的意思是,构造函数中的一个 foreach 循环将作者复制到一个新的列表集合中。
问题 2:
如果我修改了 copyofAuthor 集合中的任何内容,它不再引用原始集合正确吗?那么原始集合应该保持不变?
更新 #1:
public List<Author> Authors
{
get
{
return returnAuthors(authors);
}
}
private List<Author> returnAuthors(List<Author> copyList)
{
List<Author> getAuthors = new List<Author>();
foreach(Author copy in copyList){
getAuthors.Add(Author.Clone(copy));
}
return getAuthors;
}
我是否正确实现了我的 getter 集合,以便当它返回 List 集合时,它独立于原始集合?因此,从 getter 返回的集合中所做的任何更改都不会反映在原始集合中,对吗?
更新 #2:
使用 ReadOnlyCollection
public class Book
{
public string bookTitle {get; private set;}
private ReadOnlyCollection<Author> authors;
public string ISBN {get; private set; }
public Book(string bookTitle, ReadOnlyCollection<Author> authors, string ISBN)
{
this.bookTitle = bookTitle;
this.ISBN = ISBN;
//Is it okay to do this?
this.authors = authors;
}
public List<Author> Authors
{
get
{ //Create a shallow copy
return new ReadOnlyCollection<Author>(authors);
}
}
}
【问题讨论】:
-
我通常使用
Activator.CreateInstance来实现一个深度克隆的对象。当然,它使用反射,但对我的用例(通常希望克隆一个相当“浅”的数组)的性能影响可以忽略不计,并且代码表现力的收益超过了缺点。在您的情况下,静态克隆方法可能会满足您的目的。您是否正在寻找对您的技术的验证?如果是这样,静态Author.Clone()方法并没有什么特别的问题。与 ICloneable 相比,您从中获得的好处是您得到了实际的Author,而不是object. -
您能否描述一下导致您相信深度复制是个好主意的场景?它在时间和内存上是昂贵的,而且很难做到正确。如果您想对原始列表进行多次独立编辑,则使用持久不可变集合可能会更好。特别是考虑到作者已经是不可变的;你为什么要首先克隆一个?
-
@K.AlanBates - 非常感谢,我正在寻找此方法的验证,您能否检查我的更新并请告知?我实现了一个吸气剂,想知道我是否正确地做到了。
-
从阅读文档开始。
-
如果您正在编写代码并且您不知道为什么要编写它,那么您今天开始编写代码太早了。 在你知道你为什么要写代码之后再写代码。不要担心深拷贝与浅拷贝;这是一个很少重要的区别。考虑您的方法的使用者应该能够执行哪些操作。您考虑这些消费者是否可以改变您的收藏是绝对正确的!如果这是您关心的问题,那么不要让他们改变您的收藏。给他们一个不可变的集合。
标签: c# deep-copy shallow-copy