如何拷贝对象?使用赋值运算符拷贝的误区。
问题的提出
现定义People类如下:
public class People
{
string name;
int age;
int sex;
![]()
![]()
public string Name
{
get
{
return this.name;
}
set
{
this.name = value;
}
}
![]()
![]()
public int Age
{
get
{
return this.age;
}
set
{
this.age = value;
}
}
![]()
![]()
public int Sex
{
get
{
return this.sex;
}
set
{
this.sex = value;
}
}
![]()
}
调用程序如下:
People p1 = new People();
p1.Name = "张三";
p1.Age = 20;
p1.Sex = 1;
![]()
People p2 = p1;
![]()
p2.Name = "李四";
![]()
Console.WriteLine(p1.Name);
Console.WriteLine(p2.Name);
则输出结果是什么呢?
有些朋友认为输出结果是:
张三
李四
实际输出结果为:
李四
李四
为什么呢?因为p2其实为p1的引用,而不是副本,它们指向同一个对象。这是初学者容易犯的错误,想当然地认为p2就是p1的副本,在对p2进行改变之后,对p1的操作发生了莫名其妙的问题。
问题的解决
那么,如何获取对象的副本呢?
比较简单直接的方法是,先new一个新的对象,然后逐个复制非静态字段到新对象中。
People p1 = new People();
p1.Name = "张三";
p1.Age = 20;
p1.Sex = 1;
![]()
People p2 = new People;
![]()
p2.Name = "李四";
p2.Age = p1.Age;
p2.Sex = p1.Sex;
![]()
Console.WriteLine(p1.Name);
Console.WriteLine(p2.Name);
这样的输出结果为:
张三
李四
第二种方法是使用Object类的MemberwiseClone 方法进行浅表复制。
把 People 类改为如下实现,增加Clone方法实现对象拷贝:
public class People
{
string name;
int age;
int sex;
![]()
![]()
public string Name
{
get
{
return this.name;
}
set
{
this.name = value;
}
}
![]()
![]()
public int Age
{
get
{
return this.age;
}
set
{
this.age = value;
}
}
![]()
![]()
public int Sex
{
get
{
return this.sex;
}
set
{
this.sex = value;
}
}
![]()
public People Clone()
{
return (People)this.MemberwiseClone();
}
测试程序如下:
People p1 = new People();
p1.Name = "张三";
p1.Age = 20;
p1.Sex = 1;
![]()
People p2 = p1.Clone();
p2.Name = "李四";
![]()
Console.WriteLine(p1.Name);
Console.WriteLine(p1.Age);
Console.WriteLine(p1.Sex);
![]()
Console.WriteLine(p2.Name);
Console.WriteLine(p2.Age);
Console.WriteLine(p2.Sex);
输出结果为:
张三
20
1
李四
20
1
现定义People类如下:
public class People
{
string name;
int age;
int sex;

public string Name
{
get
{
return this.name;
}
set
{
this.name = value;
}
}

public int Age
{
get
{
return this.age;
}
set
{
this.age = value;
}
}

public int Sex
{
get
{
return this.sex;
}
set
{
this.sex = value;
}
}
}
调用程序如下:
People p1 = new People();
p1.Name = "张三";
p1.Age = 20;
p1.Sex = 1;
People p2 = p1;
p2.Name = "李四";
Console.WriteLine(p1.Name);
Console.WriteLine(p2.Name);则输出结果是什么呢?
有些朋友认为输出结果是:
张三
李四
实际输出结果为:
李四
李四
为什么呢?因为p2其实为p1的引用,而不是副本,它们指向同一个对象。这是初学者容易犯的错误,想当然地认为p2就是p1的副本,在对p2进行改变之后,对p1的操作发生了莫名其妙的问题。
问题的解决
那么,如何获取对象的副本呢?
比较简单直接的方法是,先new一个新的对象,然后逐个复制非静态字段到新对象中。
People p1 = new People();
p1.Name = "张三";
p1.Age = 20;
p1.Sex = 1;
People p2 = new People;
p2.Name = "李四";
p2.Age = p1.Age;
p2.Sex = p1.Sex;
Console.WriteLine(p1.Name);
Console.WriteLine(p2.Name);这样的输出结果为:
张三
李四
第二种方法是使用Object类的MemberwiseClone 方法进行浅表复制。
把 People 类改为如下实现,增加Clone方法实现对象拷贝:
public class People
{
string name;
int age;
int sex;

public string Name
{
get
{
return this.name;
}
set
{
this.name = value;
}
}

public int Age
{
get
{
return this.age;
}
set
{
this.age = value;
}
}

public int Sex
{
get
{
return this.sex;
}
set
{
this.sex = value;
}
}
public People Clone()
{
return (People)this.MemberwiseClone();
}
测试程序如下:
People p1 = new People();
p1.Name = "张三";
p1.Age = 20;
p1.Sex = 1;
People p2 = p1.Clone();
p2.Name = "李四";
Console.WriteLine(p1.Name);
Console.WriteLine(p1.Age);
Console.WriteLine(p1.Sex);
Console.WriteLine(p2.Name);
Console.WriteLine(p2.Age);
Console.WriteLine(p2.Sex);输出结果为:
张三
20
1
李四
20
1

浙公网安备 33010602011771号