泛型(上)
本系列文章主要意在总结笔者在学习过程中学到的有关 C# 特性的知识,分享 C# 中较为重要和突出的部分和有助养成良好编程习惯的提示。
并非旨在系统介绍 C#。
今天七夕,那就用粉色高亮吧!哈哈哈xD,大伙七夕快乐!
目录:
装箱与拆箱
理解泛型
泛型方法
小知识
装箱与拆箱:
如我们所知,object 变量能引用任何引用类型的实例。此外,object 变量也能引用值类型的实例。
Circle myCircle = new Circle();int salary = 10086;object o = myCircle; // object 变量引用引用类型实例object o = salary; // object 变量引用值类型实例
我们知道,引用类型的实例占用堆内存,使用 object 变量引用引用类型实例无非是使得 object 变量存储一个指向该堆内存区域的地址。但值类型的实例存储在栈上,使用 object 变量引用值类型,就意味着引用栈。然而,所有的引用都必须引用堆上的对象。引用栈上的数据会严重损坏“运行时”的健壮性,并造成潜在的安全漏洞,所以是不允许的。
因此,当我们执行上例中第四行的语句 object o = salary; 时,实际发生的事情是“运行时”在堆中分配一小块内存,然后 salary 的值被复制到这块内存中,最后让 o 变量引用该位于堆上的拷贝。这种将数据项从栈自动复制到堆的行为称为装箱。因此,修改 salary 变量的值, o 变量所引用的堆上的值不变。反之亦然。
装箱只会在 object 变量引用值类型时发生。
如果对值与类型有所困惑,可以参考本系列文章的第六,第七篇:C# 学习之路(六)(七)。
既然我们能用 object 变量 o 引用值的已装箱拷贝。理所当然的,我们应当能通过 o 变量获取装箱的值。
int mySalary = o; // 非法
上面的语句想要使用简单的赋值语句将 o 中的已装箱数据赋值给 mySalary 变量。但这种方式是不行的!如果上述代码合法,那么如下代码会发生什么?