深度复制而不使用序列化/反序列化



在不进行序列化/反序列化的情况下,如何深度复制类对象?

例如

public class Book
{
public string Chapter { get; set;}
public int Page { get; set;}
}
public void Main ()
{
Book newBook = new Book();
newBook.Chapter = "Physical";
newBook.Page = 40;
Book oldBook = newBook; 

newBook.Chapter = "Chemical";
newBook.Page = 60;

}
------------------------------
output
newBook.Chapter: Chemical
newBook.Page: 60
oldBook.Chapter: Chemical
oldBook.Page: 60

但是我想要这个

新书。章节:化学
新书。页码:60

旧书。章节:物理
旧书。页码:40

当对象具有足够的属性,以至于编写自定义代码会很耗时时,序列化和反序列化很流行,但您只需编写:

public static class BookExtensions
{
public static Book Clone(this Book source)
{
return new Book {Chapter = source.Chapter, Page = source.Page};
}
}

或者使其成为CCD_ 1的方法。是这样做还是创建一个扩展(如上(是一个偏好问题。如果该方法在Book中,那么如果类发生更改,则更有可能记住更新该方法。

public class Book
{
public string Chapter { get; set; }
public int Page { get; set; }
public Book Clone()
{
return new Book {Chapter = Chapter, Page = Page};
}
}

(有一个ICloneable接口你可以实现,但它并不流行。Clone方法返回object,你必须强制转换它。(

另一种方法是使用structrecord。您可能正在进行克隆,这样您就可以拥有与另一个实例相同的实例,但您可以在不更改第一个实例的情况下修改其属性。

如果您将Book类更改为struct,则此测试通过:

var book = new Book {Chapter = "x", Page = 1};
var book2 = book;
book2.Page = 2;
Assert.AreEqual(1, book.Page);

无需克隆任何内容。

或者您可以创建一个Book0:

public record class Book(string chapter, int page)
{ }

并且该测试通过:

var book = new Book("x", 1);
var book2 = book with {page = 2};
Assert.AreEqual(1, book.page);

每个Book都是不可变的。您可以将其传递给各种方法,并且每当属性需要";"改变";,像CCD_ 12这样的语句创建一本新书并且只更新指定的属性。无需克隆。

还可以使用AutoMapper库创建对象的深度副本。更多详细信息请点击此处:https://stackoverflow.com/a/74089319/6158341

最新更新