| 设为首页 加入收藏 |
当前位置: |
| TOP | ||||||||||||||||||
|
把 ref 和 out 关键字说透 (二)
传入引用类型的目的是把一个已经存在的对象的地址传过去,而如果你只是进行了 object a 声明,并没做复制,这行代码跟没做任何事! 所以,除非你使用了 out 关键字,在不用关键字和用 ref 关键字的情况下,你都必须事先复制。 out 只是一种特殊的 return
总结:现在你是否明白,当变量什么情况下该用什么关键字了吗?其实有时候 ref 和 out 都可以达到目的,你需要根据你的初衷,和它们的特点,来衡量一下到底使用哪个了! 另外,我们来看看两个同样的函数,用 out 和 ref 时候的 IL 代码 原函数:
IL代码:
发现了吗? 它们在函数内部完全是一样的!因为他们的原理都是传入了这个变量的引用。只是 out 关键字前面出现了一个标记 [out] 它们在原理上的区别主要在于编译器对它们进行了一定的限制。 最上面“代码段一”中的问题你现在明白了吗?
问题二:关于引用类型对于值类型来说,最难区别的是 ref 和 out,而对于引用类型来说就不同了。 首先,引用类型传的是引用,加了 ref 以后也是引用,所以它们是一样的?暂时我们就这么认为吧~ 我们暂时认为它们是一样的,并统称为:传引用。 所以,对于引用类型来说,out 和 传引用 的区别跟对于值类型传 ref 和 out 的区别类似,具体适用场景也和值类型类似,所以就不多加阐述了。
虽然我们说直接传和加 ref 都可以统称为传引用,但是它们还是有区别的!而且是一个很隐蔽的区别。 我们再来看一下最上面的代码段二:
out 关键字就相当于 return ,所以内部赋值为 null ,就相当于 return 了 null 可是,为什么引用类型还要加 ref 呢?它本身部已经是引用了吗?为什么加了以后就会有天大的区别呢?!
用一句话概括就是:不加 ref 的引用是堆引用,而加了 ref 后就是栈引用! @_@ 好搞啊。。什么跟什么?让我们一步步说清楚吧!
正常的传递引用类型: 加了 ref 的传递引用类型: 这两张图对于上面那句话的解释很清楚了吧? 如果直接传,只是分配了一个新的栈空间,存放着同一个地址,指向同一个对象。 内外指向的都是同一个对象,所以对 对象内部的操作 都是同步的。 但是,如果把函数内部的 obj2 赋值了 null,只是修改了 obj2 的引用,而 obj1 依然是引用了原来的对象。 所以上面的例子中,外部的变量并没有收到影响。 同样,如果内部的对象作了 obj2 = new object() 操作以后,也不会对外部的对象产生任何影响!
而加了 ref 后,传入的不是 object 地址,传入的是 object 地址的地址! 所以,当你对 obj2 赋 null 值的时候,其实是修改了 obj1 的地址,而自身的地址没变,还是引用到了 obj1
虽然在函数内部的语句是一样的,其实内部机制完全不同。我们可以看一下IL代码,一看就知道了!
|
||||||||||||||||||
| 评论 |
|
|