关于C#编程中引用与值类型赋值的一些容易犯错的地方
值类型与引用类型的区别在于:值类型在赋值的时候是拷贝值,引用类型在赋值的时候的拷贝引用。记住这一个原则,我们再来分析一些具体情况:
PointStruct pt1 = new PointStruct(,);
PointStruct pt2 = pt1;
PointStruct[] ptsArray = new PointStruct[];
ptsArray[] = pt1;
ptsArray[] = 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[].X, ptsArray[].Y, ptsArray[].X, ptsArray[].Y));
Console.WriteLine(string.Format("ptsList[0]:x:{0},y:{1},ptsList[1]:x:{2},y:{3}",
ptsList[].X, ptsList[].Y, ptsList[].X, ptsList[].Y));
Console.WriteLine(string.Format("pts2List[0]:x:{0},y:{1},pts2List[1]:x:{2},y:{3}",
pts2List[].X, pts2List[].Y, pts2List[].X, pts2List[].Y));
Console.WriteLine(string.Format("pts3List[0]:x:{0},y:{1},pts3List[1]:x:{2},y:{3}",
pts3List[].X, pts3List[].Y, pts3List[].X, pts3List[].Y));
pt2.X = ;
pt1.Y = -;
ptsArray[].X = ;
ptsArray[].Y = ;
ptsList[] = new PointStruct(, );
pts2List[] = new PointStruct(-, -);
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[].X, ptsArray[].Y, ptsArray[].X, ptsArray[].Y));
Console.WriteLine(string.Format("ptsList[0]:x:{0},y:{1},ptsList[1]:x:{2},y:{3}",
ptsList[].X, ptsList[].Y, ptsList[].X, ptsList[].Y));
Console.WriteLine(string.Format("pts2List[0]:x:{0},y:{1},pts2List[1]:x:{2},y:{3}",
pts2List[].X, pts2List[].Y, pts2List[].X, pts2List[].Y));
Console.WriteLine(string.Format("pts3List[0]:x:{0},y:{1},pts3List[1]:x:{2},y:{3}",
pts3List[].X, pts3List[].Y, pts3List[].X, pts3List[].Y));
其中PointStruct是一个值类型,我们先看结果:
从结果上可以看出来,值类型基本上都是各管各的,互不干扰,最后的pts2List与pts3List是同一个引用,所以修改其中任意一个是会影响另外一个的,数组,列表集合都会这样,因为其实就是同一个对象,只是取了2个名字而已,所以不管这个对象是否是值类型。
我们再看下面的代码:
PointReference pt1 = new PointReference(, );
PointReference pt2 = pt1;
PointReference[] ptsArray = new PointReference[];
ptsArray[] = pt1;
ptsArray[] = 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[].X, ptsArray[].Y, ptsArray[].X, ptsArray[].Y));
Console.WriteLine(string.Format("ptsList[0]:x:{0},y:{1},ptsList[1]:x:{2},y:{3}",
ptsList[].X, ptsList[].Y, ptsList[].X, ptsList[].Y));
Console.WriteLine(string.Format("pts2List[0]:x:{0},y:{1},pts2List[1]:x:{2},y:{3}",
pts2List[].X, pts2List[].Y, pts2List[].X, pts2List[].Y));
Console.WriteLine(string.Format("pts3List[0]:x:{0},y:{1},pts3List[1]:x:{2},y:{3}",
pts3List[].X, pts3List[].Y, pts3List[].X, pts3List[].Y));
pt2.X = ;
pt1.Y = -;
ptsArray[].X = ;
ptsArray[].Y = ;
ptsList[] = new PointReference(, );
pts2List[] = new PointReference(-, -);
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[].X, ptsArray[].Y, ptsArray[].X, ptsArray[].Y));
Console.WriteLine(string.Format("ptsList[0]:x:{0},y:{1},ptsList[1]:x:{2},y:{3}",
ptsList[].X, ptsList[].Y, ptsList[].X, ptsList[].Y));
Console.WriteLine(string.Format("pts2List[0]:x:{0},y:{1},pts2List[1]:x:{2},y:{3}",
pts2List[].X, pts2List[].Y, pts2List[].X, pts2List[].Y));
Console.WriteLine(string.Format("pts3List[0]:x:{0},y:{1},pts3List[1]:x:{2},y:{3}",
pts3List[].X, pts3List[].Y, pts3List[].X, pts3List[].Y));
其中PointReference是引用类型,先看看结果:
从结果上看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#编程中引用与值类型赋值的一些容易犯错的地方的更多相关文章
- C#中,为什么在值类型后面加问号
在C#中,声明一个值类型或引用类型的变量,无论是否给这个变量赋初值,该变量都有默认值: 比如声明引用类型变量: string a,其等效于string a = null,string的默认值为null ...
- Asp.net MVC 中Controller返回值类型ActionResult
[Asp.net MVC中Controller返回值类型] 在mvc中所有的controller类都必须使用"Controller"后缀来命名并且对Action也有一定的要求: 必 ...
- Controller 中Action 返回值类型 及其 页面跳转的用法
•Controller 中Action 返回值类型 View – 返回 ViewResult,相当于返回一个View 页面. -------------------------------- ...
- Web API中的返回值类型
WebApi中的返回值类型大致可分为四种: Void/ IHttpActionResult/ HttpResponseMessage /自定义类型 一.Void void申明方法没有返回值,执行成功后 ...
- C#中引用类型和值类型
C#的值类型包括:结构体(数值类型,bool型,用户定义的结构体),枚举,可空类型. C#的引用类型包括:数组,用户定义的类.接口.委托,object,字符串. 值类型和引用类型的区别在于,值类型的变 ...
- C#中引用类型和值类型的区别,分别有哪些
C#的值类型包括:结构体(数值类型,bool型,用户定义的结构体),枚举,可空类型. C#的引用类型包括:数组,用户定义的类.接口.委托,object,字符串. 数组的元素,不管是引用类型还是值类型, ...
- C#中 哪些是值类型 哪些是引用类型
DateTime属于 结构类型,所以是 值类型 在 C#中 简单类型,结构类型,枚举类型是值类型:其余的:接口,类,字符串,数组,委托都是引用类型
- 在JavaScript中引用类型和值类型的区别
一.存储方式不一样 基本数据类型 变量存储的是简单的数据段,存储的是具体的值,是轻量级的数据存储方式 引用类型 引用类型的值,可以由多个值构成的对象,引用类型的变量存储的是对象引用地址.引用类型是重量 ...
- MVC 中Controller返回值类型ActionResult
下面列举Asp.net MVC中Controller中的ActionResult返回类型 1.返回ViewResult视图结果,将视图呈现给网页 public ActionResult About() ...
随机推荐
- SHell命令总结
cat files-to-copy.txt | xargs -i cp {} /tmp
- codeforces B. Prison Transfer
题意:输入n,t,c,再输入n个数,然后问有多少个连续区间内的最大值小于等于t; #include <cstdio> #include <cstring> #include & ...
- bzoj2539
这道题真的不难,但是细节挺多(具体见程序)题目本身而言,显然是个费用流模型(或者写KM) type node=record point,next,flow,cost:longint; end; ..] ...
- 【宽搜】ECNA 2015 D Rings (Codeforces GYM 100825)
题目链接: http://codeforces.com/gym/100825 题目大意: 给你一张N*N(N<=100)的图表示一个树桩,'T'为年轮,'.'为空,求每个'T'属于哪一圈年轮,空 ...
- HDOJ(HDU) 2109 Fighting for HDU(简单排序比较)
Problem Description 在上一回,我们让你猜测海东集团用地的形状,你猜对了吗?不管结果如何,都没关系,下面我继续向大家讲解海东集团的发展情况: 在最初的两年里,HDU发展非常迅速,综合 ...
- 高效算法——M 扫描法
In an open credit system, the students can choose any course they like, but there is a problem. Some ...
- Square(强大的剪枝)
http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=2410 /* 题意; 给出一定数量的棍子用这 ...
- 怎么调试EXC_BAD_ACCESS错误
当你遇到了一个EXC_BAD_ACCESS错误,我通常会给开发者几个建议: 1.在可执行选项中设置NSZombieEnabled参数,这有时会帮缩小问题的范围: 2.运行apple的内存检测工具,如 ...
- greenplum和postgresql
想着要不要写,两个原因"懒"和"空".其实懒和空也是有联系的,不是因为懒的写,而是因为对PostgreSQL和Npgsql的知识了解匮乏,也就懒得写.好了,开头 ...
- 常用的Linux操作一
Linux 常用的操作必须明白. 1.ls 和ll 列出文件的目录. 2.tail -f XXX 查看文件. 3.chmod -R 777 XXX.jar 赋予权限 4.cat 查看文件 -n 对 ...