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

             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. JavaScript基础:数据类型的中的那些少见多怪

    原文:JavaScript基础:数据类型的中的那些少见多怪 Javascript共有6种数据类型,其中包括3个基本数据类型(string,number,boolean).2个特殊数据类型(undefi ...

  2. .net 开发框架

    .NET开发人员值得关注的七个开源项目 2010年07月02日09:33 it168网站原创 作者:黄永兵 编译 编辑:胡铭娅 我要评论(0) [IT168技术分析]微软近几年在.NET社区开源项目方 ...

  3. bzoj3709

    首先明显会想到贪心对于那些怪物回血比耗血多的,我们显然应该先打耗血少的那些回血比耗血多的怎么办呢?由于不管怎么打(假设体力负数了还能打),最终体力是一定,我们从最终体力倒推,相当于先吃药掉血,打怪物回 ...

  4. 数据结构(Splay平衡树):COGS 339. [NOI2005] 维护数列

    339. [NOI2005] 维护数列 时间限制:3 s   内存限制:256 MB [问题描述] 请写一个程序,要求维护一个数列,支持以下 6 种操作:(请注意,格式栏 中的下划线‘ _ ’表示实际 ...

  5. Eclipse集成环境中Android SDK下载及更新失败解决方案

    由于公司新项目比较忙,有好长一段时间没碰Android开发咯! 近期闲来在网上下了个开源的应用想拿来自己学习下其中的源码及整体设计,当我把下下来的项目导入Eclipse中时,报如下警告: 原因是我本地 ...

  6. C# RAS 非对称加密类 支持长字符串

    /// <summary> /// ikmb@163.com /// </summary> public class MyRAS { /// <summary> / ...

  7. iOS 沙盒路径操作:新建/删除文件和文件夹

    http://blog.csdn.net/totogo2010/article/details/7671144

  8. jQuery整体架构源码解析

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

  9. Ueditor 1.4.3 jsp utf-8版图片上传问题

  10. 高效的DDoS攻击探测与分析工具——FastNetMon

    一.简介 FastNetMon这是一个基于多种抓包引擎(NetFlow, IPFIX, sFLOW, netmap, PF_RING, PCAP)的DoS/DDoS攻击高效分析工具,可以探测和分析网络 ...