In general, objects in C# cannot be copied.
However, many specific objects provide ways to duplicate themselves. Usually this is indicated by implementing the ICloneable
interface. For example, string
implements ICloneable
so you can create a new string with the same value as an existing string by calling String.Clone
and casting the result from an object
to a string
. Since strings are immutable, this isn't very useful. You never need to clone a string to protect it's value from changing, because it can't be changed. For other objects, though, it's more useful.
Arrays can also be cloned. For example:
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"
Because arrays contain references to objects, cloning the array won't clone all the objects in the array.
myArray[1].Parameter = "changed parameter";
myOtherArray[1].Parameter // value is now "changed parameter"
Here there are two different arrays, with two different objects in the third spot, but the same object in the second spot.
Generally, Clone
is "messy". Many complicated objects are not cloneable, and just because an type implements ICloneable
doesn't mean it works as expected. Clone
usually creates what's called a shallow copy, which means that the object itself is cloned, but other objects it references are not cloned. Sometimes Clone
will create a deep copy, where all references the object has are cloned too. Sometimes it will mix them. Sometimes developers inherit from types which implement ICloneable
but don't provide a new implementation for their subtype. Sometimes they forget to make their implementations virtual. All the problems with ICloneable
are outside the scope of this answer but, as a rule, avoid Clone
if at all possible.
Instead, use copy constructors if available. Many objects can be created using a reference to other objects of the same type as a template. For example
var myList = new List<string>(){"a","b"};
var myOtherList = new List<string>(myList); // a copy of myList!
You can also use the linq extensions to turn arrays and lists into copied arrays and lists.
using System.Linq;
// ...
var myArray = new[]{"a","b"};
var myOtherArray = myArray.ToArray(); // creates a new array
var myList = myArray.ToList(); // creates a new list
In your example, try
using System.Linq;
// ...
nextMove[i] = nextCell;
listOfNextMoves.Add(new State(nextMove.ToArray()));
nextMove[i] = Cell.Empty;