C#/.Net

C#引用类型的“反常情况”

简介

大部分的开发语言都会有引用类型与值类型,基本上所有的开发人员都能理解两者之间的区别,并使用;这里讲述几个例子看一看引用类型有哪些“反常”的情况,借此深入了解一下C#中引用类型。

本文以下使用VS2013、.Net4.5、控制台应用程序。

1. Test Zero

下边这个例子只要不是初学者很容易看出来输出的结果。
(这里使用了Newtonsoft.Json,只是为了让结果直观一些)

这就是引用类型最简单的表现——使用同一块内存地址;虽然的是修改dic_2,但是上边dic_1 = dic_2;将它们绑定起来,故而结果是相同的。

但是下边一个例子有那么一点点反常。

2. Test One

猜一猜这里输出的结果会是什么?
最容易想到的便是dic1={2:2};dic2={1:1,2:2};

因为test_one_part()将dic1重新new了,并重新加入{2:2},dic2操作很常规。接下来看结果:


然而结果跟我们想要的差的很多,从结果看来dic1好像完全没有受到test_one_part()的任何影响,根据一般对于引用类型的了解,在test_one_part()内部的修改引用类型的传入参数,必然会像dic2一样将结果体现到test_one()中的dic_2。

这明显不符合我们认识的“引用类型”。

结论一:引用类型在其他方法中被重新new以后不会改变原有对象的值。

3. Test Two

再看一个稍微绕一点的:

test_two()和刚才的test_one()一样,但是test_two_part()有了一些变动。
按照常规思路再次分析一下:

代码看完了,初步的分析也有了,那么预测一般情况下的输出结果:
dic1={1:1,2:2};dic2={1:1,2:2};

执行结果如下图:

dic1又没有追加到值{2,2},然而dic2内却包含了{2,2},好吧再没有搞明白内部原理的情况下只能从结果倒推出一些猜测。

结论二:引用类型在其他方法中被重新赋值以后不会改变原有对象的值。

4. Test Three

下边这个例子可以帮我们理解上边的问题:

结果如下:

虽然有dic_0 = dic_1;dic_1 = dic_2;
但是从结果看出来dic_0 != dic_2;并不是dic_0 = dic_1 = dic_2。

5. 总结

其实结论一与结论二是一样的,都是再dic1直接被赋值发生了改变,将另外的一个内存地址赋给了dic1;根本上只要理解的引用类型赋值的原理,这些就很容易理解;值类型的赋值的修改内存中存储的值,引用类型修改的是指向值的指针(内存地址)。

Tset_One与Test_Two分了两个方法test_two();test_two_part();第一个方法中的变量被传入第二个方法中时,应该理解为前一个变量的copy;test_two_part()中变量一旦重新赋值,内存地址即被修改,原有方法外的变量地址不会受到影响。两层方法有一定的迷惑,Test_Three中就可以明显看的出来端倪。

所以以上例子的原因就很明确了,我们的引用类型还是引用类型。

.
.
.
.
.
.
.
.
【本文章出自NM1024.com,转载请注明作者出处。】

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据