C#中有兩種類型變量,一種是值類型變量,一種是引用類型變量。對於前者,copy是屬於全盤復制;
而對於後者,一般的copy只是淺copy,相當於只傳遞一個引用指針一樣。因此對於後者進行真正copy的時候,也是最費事的,具體的說,必須為其實現ICloneable接口中提供的Clone方法,示例代碼如下:
public class Test
{
public class Person : ICloneable
{
public int ID;
public int age;
public void Show()
{
Console.WriteLine("ID:{0} 年齡:{1}",ID, age);
}
public object Clone()
{
Person newPerson = new Person();
newPerson.ID = this.ID;
newPerson.age = this.age;
return newPerson;
}
}
public static void ShowPersons(Person[] persons)
{
for (int i=0; i<persons.GetLength(0); i++)
{
persons[i].Show();
}
}
static void Main(string[] argv)
{
Random rnd = new Random(unchecked((int)DateTime.Now.Ticks));
Person[] persons = new Person[4];
for (int i=0;i<persons.GetLength(0);i++)
{
persons[i] = new Person();
persons[i].ID = rnd.Next()%10;
persons[i].age = rnd.Next()%50;
}
//打印原始數組 Console.WriteLine("打印原始數組");
ShowPersons(persons);
//深拷貝 Person[] personsCopIEd = new Person[4];
for (int i=0;i<personsCopIEd.GetLength(0);i++)
{
personsCopIEd[i] = (Person)persons[i].Clone();
}
//persons.CopyTo(personsCopIEd, 0); Console.WriteLine("深拷貝的數組");
ShowPersons(personsCopIEd);
// //淺拷貝
// Person[] personsCloned = (Person[])persons.Clone();
// Console.WriteLine("淺拷貝的數組");
// ShowPersons(personsCloned);
//對原數組做修改 persons[2].ID += 10;
Console.WriteLine("打印修改後的原始數組");
ShowPersons(persons);
Console.WriteLine("深拷貝的數組應該不改變");
ShowPersons(personsCopIEd);
// Console.WriteLine("淺拷貝的數組應該改變");
// ShowPersons(personsCloned); }
}
某次的運行結果:
對於上例,在進行深拷貝時,必須先為對象數組new新的空間,而數組中的對象成員則由實現了接口的相應方法分配新的空間,由深拷貝出來的新對象數組不會因為原數組的改變而改變,相反,對於注釋行中僅作了淺表復制的personsCloned而言則會受原數組的影響。
另外注意 persons.CopyTo(personsCopied, 0); 這一句並不是對personsCopIEd進行深表復制,數組直接拷貝是拷貝的指向同一個對象的引用,因為在C#中對於存放引用類型的數組,數組本身的引用類型和數組中元素的引用類型不能混為一談,此時的數組僅相當於一個容器,所以對於容器本身和容器中存放的東西是要分別進行實例化的。呵呵困擾我很多天的問題貼上來做個備忘哈