一、万物之父
关键字:object
1.概念
object是所有类型的基类,它是一个类(引用类型)
2.作用
1.可以利用里氏替换原则,用object容器装所有对象
2.可以用来表示不确定类型,作为函数参考类型
Father f =new Son();
if(f is son)
{
(f as Son).speak();
}
//引用类型
object o =new Son();
//用is as 来判断和转换
if(o is Son)
{
(o as son).speak();
}
//值类型
boject o2 =1f;
//用强转
float fl =(float)o2;
//特殊的string类型
object str ="1231";
string str2 = str as string;/string str2 = str.ToString();
object arr =new int[10];
//尽量用as
int[] ar = arr as int[];/int[] ar =(int[])arr;
简单理解object,它就是可以用来装载所有变量类型对象的容器。它可以表示任意对象,我们可以通过as转换,可以通过括号强转,可以通过ToString转换。
二、装箱拆箱
1.概念
装箱:
把值类型用引用类型存储,栈内存会迁移到堆内存中。
拆箱:
把引用类型存储的值类型取出来,堆内存会前移到栈内存中。
2.发生条件:
值类型 转换为 引用类型(装箱)
int val = 100;
object obj = val;
Console.WriteLine ("对象的值 = {0}", obj); //对象的值 = 100
引用类型 转换为 值类型(拆箱)
int val = 100;
object obj = val;
int num = (int) obj;
Console.WriteLine ("num: {0}", num); //num: 100
装箱拆箱的内部操作
.NET中,数据类型划分为 值类型 和 引用 (不等同于C++的指针) 类型 ,与此对应,内存分配被分成了两种方式,一为栈,二为堆,注意:是托管堆。
值类型只会在栈中分配。 引用类型分配内存与托管堆。(托管堆对应于垃圾回收。)
在C#中,值类型是直接将数据存储在栈空间中;而引用类型是将数据存储在堆空间中,同时在栈空间中存储一个对该数据的引用。
装箱操作
PS:o 和 i 的改变将互不影响,因为装箱使用的是 i 的一个副本。
对值类型在堆中分配一个对象实例,并将该值复制到新的对象中。按三步进行。
1:首先从托管堆中为新生成的引用对象分配内存(大小为值类型实例大小加上一个方法表指针和一个SyncBlockIndex)。
2:然后将值类型的数据拷贝到刚刚分配的内存中。
3:返回托管堆中新分配对象的地址。这个地址就是一个指向对象的引用了。
可以看出,进行一次装箱要进行分配内存和拷贝数据这两项比较影响性能的操作。
拆箱操作
PS:o 和 i 的改变将互不影响(已验证)。
1、首先获取托管堆中属于值类型那部分字段的地址,这一步是严格意义上的拆箱。
2、将引用对象中的值拷贝到位于线程堆栈上的值类型实例中。
经过这2步,可以认为是同boxing是互反操作。严格意义上的拆箱,并不影响性能,但伴随这之后的拷贝数据的操作就会同boxing操作中一样影响性能。
原文链接:https://blog.csdn.net/qiaoquan3/article/details/51439726
4.优缺点
好处:不确定类型时可以方便参数的存储和传递
坏处:存在内存迁移,增加性能消耗