如何拷贝对象?使用赋值运算符拷贝的误区。
2007-11-21 15:31
253 查看
问题的提出
现定义People类如下:
public class People
调用程序如下:
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
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
调用程序如下:
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
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
相关文章推荐
- java提高篇-----使用序列化实现对象的拷贝
- 如何使用List.toArray()转换为数组对象
- 如何使用 PageSettings 对象和 PageSetupDialog 控件允许用户选择各种打印选项
- 如何使用 ADO Stream 对象访问和修改 SQL Server BLOB 数据
- 如何使用List.toArray()转换为数组对象
- 如何设计和使用自定义的权限对象(自定义权限检查函数)
- Struts2中如何使用session、request等对象
- svn如何使用import目录作为工作拷贝+我的svn学习笔记
- 【转】如何使用代码动态设置水晶报表中的文本,字段等对象呢?
- 如何使用 Git 管理二进制大对象
- java提高篇(五)-----使用序列化实现对象的拷贝
- request和response对象(疑问:为什么servlet和jsp中可以直接使用req和res对象?如何理解内置的含义?)
- 如何使用memcpy向容器里拷贝数据
- JavaScript中访问节点对象的方法有哪些如何使用
- 关于jsp内置对象Session和Cookie使用的肤浅理解,如何使用Session来统计网站在线人数
- 如何使用==操作符,Equals方法,ReferenceEquals方法,IEquatable接口比较2个对象
- 关于如何将一个对象保存到本地文件之ObjectOutputStream、ObjectInputStream的使用小结。
- 使用反射+缓存+委托,实现一个不同对象之间同名同类型属性值的快速拷贝
- 下面的示例演示如何使用传递到事件处理方法的 GridViewCommandEventArgs 对象确定引发事件的按钮的命令名。
- 顶级手游如何使用移动广告?6大误区要注意