如何复制对象的实例,如果该对象发生更改,则实例不会?

时间:2015-02-27 00:28:34

标签: c#

我有一个非常简单的问题需要花费很长时间来弄清楚...如何复制项目的对象,如果该对象发生变化,实例不会?

例如,在我的代码中我有这个:

nextMove[i] = nextCell;
listOfNextMoves.Add(new State(nextMove));
nextMove[i] = Cell.Empty;

我已添加到listOfNextMoves的nextMove更改为第三行所做的更改....如果nextMove [i]更改,如何更改,列表中的nextMove不会更改?

在python中,如果我想做

tempBoard = genBoard

我必须这样做

tempBoard = list(genBoard)

如果我不清楚,我很抱歉,我已经坚持了一段时间。

3 个答案:

答案 0 :(得分:3)

ToList()函数创建列表的副本:

nextMoveCopy = nextMove.ToList();

您还可以将构造函数用于大多数集合类:

nextMoveCopy = new ArrayList(nextMove); 
nextMoveCopy = new List< GameBoard >(nextMove); 
nextMoveCopy = new ObservableCollection< GameBoard >(nextMove); 

请勿使用ReadOnlyCollection。它不是制作副本,而是在原始列表周围创建一个只读包装器。

答案 1 :(得分:1)

通常,无法复制C#中的对象。

但是,许多特定对象提供了复制自身的方法。通常通过实现ICloneable接口来指示。例如,string实现了ICloneable,因此您可以通过调用String.Clone并将结果从object转换为{来创建一个与现有字符串具有相同值的新字符串{1}}。由于字符串是不可变的,因此这不是非常有用。您永远不需要克隆字符串以保护其值不变,因为它无法更改。但是,对于其他对象,它更有用。

也可以克隆阵列。例如:

string

因为数组包含对象的引用,所以克隆数组不会克隆数组中的所有对象

var myArray = new MyType[3];
myArray[1] = new MyType("some parameter");
myArray[2] = new MyType("some other parameter");
var myOtherArray = (myArray[]) myArray.Clone();
myOtherArray[2].Parameter // value is "some other parameter"
myOtherArray[2] = new MyType("a whole other parameter");
myOtherArray[2].Parameter // value is "a whole other parameter"
myArray[2].Parameter // value is still "some other parameter"

这里有两个不同的数组,第三个位置有两个不同的对象,但第二个位置是相同的对象。

通常,myArray[1].Parameter = "changed parameter"; myOtherArray[1].Parameter // value is now "changed parameter" 是&#34;凌乱&#34;。许多复杂的对象不可复制,只是因为类型实现Clone并不意味着它按预期工作。 ICloneable通常创建称为浅拷贝的东西,这意味着对象本身是克隆的,但它引用的其他对象不会被克隆。有时Clone将创建一个深层副本,其中也克隆了对象所有的引用。有时它会混合它们。有时开发人员继承实现Clone的类型,但不为其子类型提供新的实现。有时他们忘记让他们的实现变得虚拟。 ICloneable的所有问题都超出了此答案的范围,但通常尽可能避免使用ICloneable

相反,如果可用,请使用复制构造函数。可以使用对与模板相同类型的其他对象的引用来创建许多对象。例如

Clone

您还可以使用linq扩展将数组和列表转换为复制的数组和列表。

var myList = new List<string>(){"a","b"};
var myOtherList = new List<string>(myList); // a copy of myList!

在您的示例中,请尝试

using System.Linq;
// ...
var myArray = new[]{"a","b"};
var myOtherArray = myArray.ToArray(); // creates a new array
var myList = myArray.ToList(); // creates a new list

答案 2 :(得分:0)

我想我明白了!

我只需要做

nextMove[i] = nextCell;
listOfNextMoves.Add(new State((Cells[])nextMove.Clone()));
nextMove[i] = Cell.Empty;

它为我创建了一个深度的实例副本!