值类型,引用类型的初始化,等值判断,传递和转换

初始化

首先我们来看这段 代码1

 

发现什么,编译通过,运行时 call 值类型没有问题,call 引用类型却报错。

再看如下 代码2

直接编译就不通过,什么原因呢

原因在于在class的构造器会自动对所有field自动初始化,所以代码1编译可以通过,代码2方法里的私有字段确无法通过编译。

值数据直接对应的是堆栈,一初始化就自动运行值类型默认的构造器,而引用类型堆栈里的是一个空指针,指向的数据为空。

代码1等价于如下 代码3

正因为值类型将自动call constructor, 避免编程的混乱,.net也不允许值类型自定义无参构造器,因此我们编写struct的时候,也无法自定义无参构造器。

另外在类里用户如果已经有了自定义的构造器,那么编译顺序是首先编译类里字段的初始化,然后再调用自定义构造器。

等值判断和参数传递

还是看代码4

 

运行结果数值类型和截然不同,怎么造成的呢

所谓等值判断 所判断的就是堆栈里的内容。值类型堆栈里存放就是实际内容,所以值类型的等值判断就是判断数据相同,对于.net来说,就是通过反射,对比2个值类型的内部所有数据是否相同,全部相同则2个值类型相同

而对于引用类型,堆栈里存放的只是地址,只有地址完全相同,2个引用类型才相同,而不管实际对应的数据是什么。

所以开始的2个有相同的数值的值数据做对比返回true,而2个有相同数据的引用类型则返回false。

当2个数据传递的时候,就是1方把堆栈里的数据复制给另一方。对于值类型来说,堆栈里的就是数据,赋值消耗较大,而对于引用类型来说,堆栈里存放的只是1个地址,指向真实数据的地址。

所以当存在2个相等的引用类型,由于存在相同的地址。另一方改变数据,都将影响另一方。

而2个相等的值类型,由于堆栈存的就是数据,1方改变,对另一方没有任何影响。

因此第3个判断为2个值类型,1方改变不影响另一方,返回false,第4个判断2个引用类型,双方一起变化,返回true。

 

注意:string有点不一样,是引用类型,但是确是数值恒定的引用类型,CLR特别开辟了一个驻留表来保存所有的string数值,所以传递的时候传递的是指针,但数据改变不是影响原来的数据,而是新开一个空间给新数据.

 

转换

   转换可以分2大类

   第1类为运算符转换,转换的时候调用类里的转换运算符,又包含implicit operator(隐性转换) explicit operator(显性转换),如:int i=1;long l=1;l=i;i=(int)l;

这里l=i就是隐性转换,i=(int)l为显性转换。

   第2类为由于继承关系而产生的转换,子类向父类(或接口)的转换(传递)

    如:Employee e=new Employee(); IEmployee ie=e;

    这里传递的是指针。虽然语法跟上面运算法转换一样,但实际工作并不一样。

    注意:当转换失败的时候运行将会报错。

     另外还有专门给类转换用的as转换符,语法如:IEmployee ie=e as IEmployee;

as转换符不支持operator的转换,只传递指针地址。

   另外:当as转换失败的时候,并不会报错,而是传递一个空指针,得到1个null数据。

 

值类型与引用类型之间的转换

   上节提到的转换时值类型与值类型,引用类型和引用类型之间的转换,如果是值类型与引用类型之间的转换呢

   如object与int之间的转换。

   1:值类型转为引用类型,首先将堆栈中值的数据复制到堆里,然后将指针传给引用类型,此步骤称为box(装箱)

   2:引用类型转为值类型。根据引用指针获得数据内容,然后把堆中的数据拷贝到堆栈,此步骤称为unbox(拆箱)

  显然从这里看的出box与unbox消耗大量资源,及其影响效率,所以对于未知类型的数据应该尽量用泛型,避免使用类似ArrayList等类。

 

 参考

《applied microsoft .net framework Programming》

《Professional c#》

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值