读CLR via C#总结(7) 以传引用的方式向方法传递参数---refout
默認情況下,CLR假定所有方法參數都是傳值的。
對于引用類型,對一個對象的引用(指向對象的一個指針)會傳給方法,但是這個引用本身是以傳值的方式傳給方法的。方法能修改對象,調用者能看到這些修改。
對于值類型,傳給方法的是實例的一個副本。方法獲得的是一個值類型實例副本,所以調用者中的實例不受影響。
代碼如下:
?
一,為值類型使用ref和out
namespace refDemo2 {class Program{static void Main(string[] args){int i = 5;AddI(ref i);Console.WriteLine(i);//顯示"15",i的值被改變了 Console.ReadKey();}private static void AddI(ref int v)//v獲得的是一個指向實例對象(值5)的指針 {v+= 10;}} }?
二,為引用類型使用ref和out
?
namespace refDemo3 {class Program{static void Main(string[] args){string s1 = "Tmac";string s2 = "Mcgrady";Swap(s1,s2);//沒有使用refConsole.WriteLine(s1);//顯示"Tmac"Console.WriteLine(s2);//顯示"Mcgrady",為什么值沒有交換呢??? }private static void Swap(string a, string b)//a和b獲取的是一個分別指向對象s1和s2的指針 {string t = b;b = a;a = t;}} }?
容易困惑的地方:s1,s2是引用類型,傳給方法Swap的肯定也是指向實例的一個指針,那理論上來講調用了Swap方法之后s1和s2的值要交換呀,可是實際結果并不如我們所愿,這是為什么呢?
答:就如文章一開頭講的,默認情況下,CLR假定所有方法參數都是傳值的,雖然s1和s2是引用類型,調用方法時傳遞的也是指向實例的指針,但是,指針本身還是以傳值方式傳給方法的。所以調用者中實例的值并沒有得到改變。
要達到我們想要的效果,所以還是必須得使用ref,代碼如下:
namespace refDemo3 {class Program{static void Main(string[] args){string s1 = "Tmac";string s2 = "Mcgrady";Swap(ref s1,ref s2);Console.WriteLine(s1);//顯示"Mcgrady"Console.WriteLine(s2);//顯示"Tmac" }private static void Swap(ref string a,ref string b)//a和b獲取的是一個分別指向對象s1和s2的指針 {string t = b;b = a;a = t;}} }?總結:1,從IL和CLR的角度看,ref和out是一樣的,它們都會生成相同的IL代碼,都導致傳遞指向實例的一個指針。
2,ref一般用在方法內部對外部的值進行改變的時候。而out一般用在方法有多個返回值的時候。
轉載于:https://www.cnblogs.com/mcgrady/archive/2012/06/09/2433403.html
總結
以上是生活随笔為你收集整理的读CLR via C#总结(7) 以传引用的方式向方法传递参数---refout的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《那些年啊,那些事——一个程序员的奋斗史
- 下一篇: urlrewrite 地址重写