关于C#编程中引用与值类型赋值的一些容易犯错的地方
2015-06-08 15:09
786 查看
值类型与引用类型的区别在于:值类型在赋值的时候是拷贝值,引用类型在赋值的时候的拷贝引用。记住这一个原则,我们再来分析一些具体情况:
其中PointStruct是一个值类型,我们先看结果:
![](https://images0.cnblogs.com/blog2015/589192/201506/081459123639592.png)
从结果上可以看出来,值类型基本上都是各管各的,互不干扰,最后的pts2List与pts3List是同一个引用,所以修改其中任意一个是会影响另外一个的,数组,列表集合都会这样,因为其实就是同一个对象,只是取了2个名字而已,所以不管这个对象是否是值类型。
我们再看下面的代码:
其中PointReference是引用类型,先看看结果:
![](https://images0.cnblogs.com/blog2015/589192/201506/081457409265325.png)
从结果上看pt1,pt2,ptsArray是相互影响的,因为PointReference是引用类型,另外ptsList是重新申请的一个类,只是添加了两个成员,成员是pt1,pt2,修改任意一个,也会影响这个ptsList,但是如果对ptsList的成员的X,Y是只读的,不能修改,所以只能重新赋值,在重新赋值后ptsList[0]都修改成1000,,1000了,但是其他的没有受影响,因为在修改以前里面存的引用是pt1,pt2的,在重新赋值后存的引用是重新new后的地址,自然不会对其他造成影响,然后pts2List也是一样的道理,修改pts2List是不会影响ptsList,但是会影响pts3List,因为他们的集合地址的引用是一样的,公用的存储空间。
我希望从这个例子中可以帮我彻底的疏通我对值类型与引用类型在运用中遇到的难题。
一些图示我就不画了,实际去分析我上传的例子就非常清楚了。
http://files.cnblogs.com/files/monkeyZhong/ReferenceTypeVSValueTypeDemo.zip
PointStruct pt1 = new PointStruct(2,2); PointStruct pt2 = pt1; PointStruct[] ptsArray = new PointStruct[3]; ptsArray[0] = pt1; ptsArray[1] = pt2; List<PointStruct> ptsList = new List<PointStruct>(); ptsList.Add(pt1); ptsList.Add(pt2); List<PointStruct> pts2List = new List<PointStruct>(); pts2List.AddRange(ptsArray); List<PointStruct> pts3List = pts2List; Console.WriteLine("值类型的数组,原始值:"); Console.WriteLine(string.Format("pt1:x:{0},y:{1},pt2:x:{2},y:{3}", pt1.X, pt1.Y, pt2.X, pt2.Y)); Console.WriteLine(string.Format("ptsArray[0]:x:{0},y:{1},ptsArray[1]:x:{2},y:{3}", ptsArray[0].X, ptsArray[0].Y, ptsArray[1].X, ptsArray[1].Y)); Console.WriteLine(string.Format("ptsList[0]:x:{0},y:{1},ptsList[1]:x:{2},y:{3}", ptsList[0].X, ptsList[0].Y, ptsList[1].X, ptsList[1].Y)); Console.WriteLine(string.Format("pts2List[0]:x:{0},y:{1},pts2List[1]:x:{2},y:{3}", pts2List[0].X, pts2List[0].Y, pts2List[1].X, pts2List[1].Y)); Console.WriteLine(string.Format("pts3List[0]:x:{0},y:{1},pts3List[1]:x:{2},y:{3}", pts3List[0].X, pts3List[0].Y, pts3List[1].X, pts3List[1].Y)); pt2.X = 10; pt1.Y = -1; ptsArray[0].X = 100; ptsArray[1].Y = 30; ptsList[0] = new PointStruct(1000, 1000); pts2List[1] = new PointStruct(-1000, -1000); Console.WriteLine("值类型的数组,修改后:"); Console.WriteLine(string.Format("pt1:x:{0},y:{1},pt2:x:{2},y:{3}", pt1.X, pt1.Y, pt2.X, pt2.Y)); Console.WriteLine(string.Format("ptsArray[0]:x:{0},y:{1},ptsArray[1]:x:{2},y:{3}", ptsArray[0].X, ptsArray[0].Y, ptsArray[1].X, ptsArray[1].Y)); Console.WriteLine(string.Format("ptsList[0]:x:{0},y:{1},ptsList[1]:x:{2},y:{3}", ptsList[0].X, ptsList[0].Y, ptsList[1].X, ptsList[1].Y)); Console.WriteLine(string.Format("pts2List[0]:x:{0},y:{1},pts2List[1]:x:{2},y:{3}", pts2List[0].X, pts2List[0].Y, pts2List[1].X, pts2List[1].Y)); Console.WriteLine(string.Format("pts3List[0]:x:{0},y:{1},pts3List[1]:x:{2},y:{3}", pts3List[0].X, pts3List[0].Y, pts3List[1].X, pts3List[1].Y));
其中PointStruct是一个值类型,我们先看结果:
![](https://images0.cnblogs.com/blog2015/589192/201506/081459123639592.png)
从结果上可以看出来,值类型基本上都是各管各的,互不干扰,最后的pts2List与pts3List是同一个引用,所以修改其中任意一个是会影响另外一个的,数组,列表集合都会这样,因为其实就是同一个对象,只是取了2个名字而已,所以不管这个对象是否是值类型。
我们再看下面的代码:
PointReference pt1 = new PointReference(2, 2); PointReference pt2 = pt1; PointReference[] ptsArray = new PointReference[3]; ptsArray[0] = pt1; ptsArray[1] = pt2; List<PointReference> ptsList = new List<PointReference>(); ptsList.Add(pt1); ptsList.Add(pt2); List<PointReference> pts2List = new List<PointReference>(); pts2List.AddRange(ptsArray); List<PointReference> pts3List = pts2List; Console.WriteLine("引用类型的数组,原始值:"); Console.WriteLine(string.Format("pt1:x:{0},y:{1},pt2:x:{2},y:{3}", pt1.X, pt1.Y, pt2.X, pt2.Y)); Console.WriteLine(string.Format("ptsArray[0]:x:{0},y:{1},ptsArray[1]:x:{2},y:{3}", ptsArray[0].X, ptsArray[0].Y, ptsArray[1].X, ptsArray[1].Y)); Console.WriteLine(string.Format("ptsList[0]:x:{0},y:{1},ptsList[1]:x:{2},y:{3}", ptsList[0].X, ptsList[0].Y, ptsList[1].X, ptsList[1].Y)); Console.WriteLine(string.Format("pts2List[0]:x:{0},y:{1},pts2List[1]:x:{2},y:{3}", pts2List[0].X, pts2List[0].Y, pts2List[1].X, pts2List[1].Y)); Console.WriteLine(string.Format("pts3List[0]:x:{0},y:{1},pts3List[1]:x:{2},y:{3}", pts3List[0].X, pts3List[0].Y, pts3List[1].X, pts3List[1].Y)); pt2.X = 10; pt1.Y = -1; ptsArray[0].X = 100; ptsArray[1].Y = 30; ptsList[0] = new PointReference(1000, 1000); pts2List[1] = new PointReference(-1000, -1000); Console.WriteLine("引用类型的数组,修改后:"); Console.WriteLine(string.Format("pt1:x:{0},y:{1},pt2:x:{2},y:{3}", pt1.X, pt1.Y, pt2.X, pt2.Y)); Console.WriteLine(string.Format("ptsArray[0]:x:{0},y:{1},ptsArray[1]:x:{2},y:{3}", ptsArray[0].X, ptsArray[0].Y, ptsArray[1].X, ptsArray[1].Y)); Console.WriteLine(string.Format("ptsList[0]:x:{0},y:{1},ptsList[1]:x:{2},y:{3}", ptsList[0].X, ptsList[0].Y, ptsList[1].X, ptsList[1].Y)); Console.WriteLine(string.Format("pts2List[0]:x:{0},y:{1},pts2List[1]:x:{2},y:{3}", pts2List[0].X, pts2List[0].Y, pts2List[1].X, pts2List[1].Y)); Console.WriteLine(string.Format("pts3List[0]:x:{0},y:{1},pts3List[1]:x:{2},y:{3}", pts3List[0].X, pts3List[0].Y, pts3List[1].X, pts3List[1].Y));
其中PointReference是引用类型,先看看结果:
![](https://images0.cnblogs.com/blog2015/589192/201506/081457409265325.png)
从结果上看pt1,pt2,ptsArray是相互影响的,因为PointReference是引用类型,另外ptsList是重新申请的一个类,只是添加了两个成员,成员是pt1,pt2,修改任意一个,也会影响这个ptsList,但是如果对ptsList的成员的X,Y是只读的,不能修改,所以只能重新赋值,在重新赋值后ptsList[0]都修改成1000,,1000了,但是其他的没有受影响,因为在修改以前里面存的引用是pt1,pt2的,在重新赋值后存的引用是重新new后的地址,自然不会对其他造成影响,然后pts2List也是一样的道理,修改pts2List是不会影响ptsList,但是会影响pts3List,因为他们的集合地址的引用是一样的,公用的存储空间。
我希望从这个例子中可以帮我彻底的疏通我对值类型与引用类型在运用中遇到的难题。
一些图示我就不画了,实际去分析我上传的例子就非常清楚了。
http://files.cnblogs.com/files/monkeyZhong/ReferenceTypeVSValueTypeDemo.zip
相关文章推荐
- c# socket 判断端口是否被占用
- c#中const与readonly区别
- [Solution] Microsoft Windows 服务(1) C#创建Windows服务
- c#中const与readonly区别
- C#二进制与字符串之间的相互转换
- C#中的反射原理及应用
- C# datatable to list
- C#中struct和class的区别
- C#基础-----面向对象(一)
- C# 类型基础
- C# 本地时间和GMT(UTC)时间的转换
- C#第四次作业
- C#高级编程第五天----流控制(控制语句)
- C#基础-----复杂数据类型
- C#面向对象设计模式纵横谈(Singleton单件)
- 预定义的类型“Microsoft.CSharp.RuntimeBinder.Binder”未定义或未导入
- How to Set Word Document Properties with C#
- C# 获取word批注信息
- C#代码性能测试类(简单实用)
- c#.net常用函数列表