值类型与引用类型的区别在于:值类型在赋值的时候是拷贝值,引用类型在赋值的时候的拷贝引用。记住这一个原则,我们再来分析一些具体情况:

             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#编程中引用与值类型赋值的一些容易犯错的地方的更多相关文章

  1. C#中,为什么在值类型后面加问号

    在C#中,声明一个值类型或引用类型的变量,无论是否给这个变量赋初值,该变量都有默认值: 比如声明引用类型变量: string a,其等效于string a = null,string的默认值为null ...

  2. Asp.net MVC 中Controller返回值类型ActionResult

    [Asp.net MVC中Controller返回值类型] 在mvc中所有的controller类都必须使用"Controller"后缀来命名并且对Action也有一定的要求: 必 ...

  3. Controller 中Action 返回值类型 及其 页面跳转的用法

        •Controller 中Action 返回值类型 View – 返回  ViewResult,相当于返回一个View 页面. -------------------------------- ...

  4. Web API中的返回值类型

    WebApi中的返回值类型大致可分为四种: Void/ IHttpActionResult/ HttpResponseMessage /自定义类型 一.Void void申明方法没有返回值,执行成功后 ...

  5. C#中引用类型和值类型

    C#的值类型包括:结构体(数值类型,bool型,用户定义的结构体),枚举,可空类型. C#的引用类型包括:数组,用户定义的类.接口.委托,object,字符串. 值类型和引用类型的区别在于,值类型的变 ...

  6. C#中引用类型和值类型的区别,分别有哪些

    C#的值类型包括:结构体(数值类型,bool型,用户定义的结构体),枚举,可空类型. C#的引用类型包括:数组,用户定义的类.接口.委托,object,字符串. 数组的元素,不管是引用类型还是值类型, ...

  7. C#中 哪些是值类型 哪些是引用类型

    DateTime属于 结构类型,所以是  值类型 在 C#中 简单类型,结构类型,枚举类型是值类型:其余的:接口,类,字符串,数组,委托都是引用类型

  8. 在JavaScript中引用类型和值类型的区别

    一.存储方式不一样 基本数据类型 变量存储的是简单的数据段,存储的是具体的值,是轻量级的数据存储方式 引用类型 引用类型的值,可以由多个值构成的对象,引用类型的变量存储的是对象引用地址.引用类型是重量 ...

  9. MVC 中Controller返回值类型ActionResult

    下面列举Asp.net MVC中Controller中的ActionResult返回类型 1.返回ViewResult视图结果,将视图呈现给网页 public ActionResult About() ...

随机推荐

  1. db2索引创建和删除

    在表trpt_jv_rpt_log_td的tim列上创建索引 create index dw_rpt.irpt_jv_rpt_log_td_tim on dw_rpt.trpt_jv_rpt_log_ ...

  2. thinkphp引入类的使用

    比如发送邮件类phpmailer 1.将核心文件放入ORG目录下 2.在使用的地方,引入这个类文件 如何引入呢? import('@.ORG.phpmailer'); 这个表示引入当前项目中的ORG中 ...

  3. AlgorithmsI PA2: Randomized Queues and Deques RandomizedQueue

    RandomizedQueue 有几个关键点: 1. 选择合适的数据结构,因为需要任意位置删除元素,Linked list 做不到,必须使用resizing arrays. 2. resizing 的 ...

  4. SQL约束和字段约束的创建和删除

    1)禁止所有表约束的SQLselect 'alter table '+name+' nocheck constraint all' from sysobjects where type='U' 2)删 ...

  5. 实战weblogic集群之创建节点和集群

    一.启动weblogic,访问控制台 weblogic的domain创建完成后,接下来就可以启动它,步骤如下: $ cd /app/sinova/domains/base_domain/bin $ . ...

  6. 网络编程-pcap数据包格式

    Libpcap的官方网站是http://www.tcpdump.org/,该项目和Tcpdump项目是同一个团队维护.Libpcap是一个平台独立的 数据包捕获开发包,制定了数据包离线存储的事实标准. ...

  7. (转载)mysql查询今天、昨天、7天、近30天、本月、上一月数据

    (转载)http://blog.163.com/dreamman_yx/blog/static/26526894201053115622827/ 查询 今天 select * from 表名 wher ...

  8. Ural1297 Palindrome(后缀数组)

        [题目链接] http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=12406 [题意] 求最长回文子串. [思路] 将字符串 ...

  9. Oulipo - HDU 1686 (KMP模板题)

    题目大意:题目叙述很多,其实只看输入输出也能明白什么意思,给两个串W,T, 判断T串中包含几个串W.   分析:还是基础的KMP应用....................... 直接上代码. === ...

  10. ActionScript 3.0数组操作

    var arr:Array=new Array();arr=["a","b","c"];  //赋初值,注意这里的即使单个字符赋值使用的是& ...