關於ref與out的區別


寫在最前面

這幾天一直在公司接受培訓,都是一些基礎的知識,同時也乘着這個機會鞏固一下自己的基礎,基礎太重要了。前些時一直看的是多線程方面的知識,接下來我會寫一些其他方面的知識,畢竟作為一個實習新人得和自己從事的具體方向靠近,不過感覺前些時的多線程學的還不夠,今后有空還會繼續,暫時到此吧、、、

昨天培訓的時候有一個問題是關於ref和out的區別,悲催的我不知道,只曉得它們可以做引用傳遞,具體區別都沒一個概念額,貌似當年教我們C#初級的尹老師提到過一個數字交換實現可以用這個,不過當時也就僅此僅此,今天來學習下下

首先聲明下哈,此文參考了網上部分文章內容,然后結合自己的了解和總結,有不對的盡管拍磚

關於ref

經常聽到值類型和引用類型,其實本質就是一個存儲值一個存儲地址,看看下面一段代碼:

 1     public class Test
 2     {
 3         public int num;
 4         public Test(int x)
 5         {
 6             this.num = x;
 7         }
 8         public void ChangeNum(Test x)
 9         {
10             x = new Test(100);
11         }
12     }
13     class Program
14     {
15         static void Main(string[] args)
16         {
17             Test ts = new Test(10);
18             ts.ChangeNum(ts);
19             Console.WriteLine(ts.num);
20             Console.ReadKey();
21         }
22     }

對於以上代碼,你認為會輸出什么結果?10?100?正確結果是10,猜100的肯定有疑問了、、、

接下來我改兩個位置,就不復制整個了,貼出改位置的兩個位置,如下所示:

    ts.ChangeNum(ref ts);    //改上面第18行
    public void ChangeNum(ref Test x)    //改上面第8行

對於這次的結果又得探討了,10?還是100?正確結果為100


以上截圖,左邊是原始代碼變量ts和x的地址,右邊是修改兩個位置后的ts和x的地址,從上面我們可以清晰的看見左圖ts地址(0x05f0eb2c)和x地址(0x05f0eacc)不同,右圖中ts的地址(0x0568ee6c)和x的地址(0x0568ee6c)相同。就是由於原始代碼中Main函數中的ts和Test中的x不是同一個變量,所以后面執行18行代碼不會對num值產生任何影響,而后面的兩行代碼就不同,因為所指向的是同一個變量,所以結果自然得以修改變為100

關於out

還是來看一段代碼,事實比較好說話,呵呵:

 1     public class Test
 2     {
 3         public int num;
 4         public Test(int x)
 5         {
 6             this.num = x;
 7         }
 8         public void ChangeNum(out Test x)
 9         {
10             x = new Test(100);
11         }
12     }
13     class Program
14     {
15         static void Main(string[] args)
16         {
17             Test ts = new Test(10);
18             Test x;
19             ts.ChangeNum(out x);
20             Console.WriteLine(ts.num);
21             Console.WriteLine(x.num);
22             Console.ReadKey();
23         }
24     }

以上這段代碼執行打印的兩個結果也是不同的,分別打印10和100,原理和上面差不多一樣,是不是感覺和上面講的ref很有點象,沒錯,所以有了今天的標題“關於ref與out的區別”,接下來談談其區別吧!

關於out和ref的區別

作為都可以作為引用傳遞,區別在於值傳遞。ref傳遞前必須初始化,而out不必初始化,就算初始化,也會被無視之,out 作為輸出參數,可以解決函數只有一個返回值的問題

 1         static void Main(string[] args)
 2         {
 3             Program pg = new Program();
 4             int x;
 5             pg.Method_1(out x);
 6             Console.WriteLine(x);
 7             int y = 1;
 8             pg.Method_2(ref y);
 9             Console.WriteLine(y);
10             Console.ReadKey();
11         }
12 
13         public void Method_1(out int x)
14         {
15             x = 2;      //這一句必須要,不然報錯
16             Console.WriteLine("調用Medthod_1");
17         }
18 
19         public void Method_2(ref int x)
20         {
21             x++;
22             Console.WriteLine("調用Medthod_2");
23         }

運行結果:

懷舊一下當年尹老師講的a=5和b=10,a與b數值交換,就是用的ref

 1         public void yy(ref int x,ref int y)
 2         {
 3             int temp;
 4             temp = x;
 5             x = y;
 6             y = temp;
 7         }
 8         static void Main(string[] args)
 9         {
10             Program pg = new Program();
11             int a = 5;
12             int b = 10;
13             Console.WriteLine("a:" + a + ",b:" + b);
14             pg.yy(ref a,ref b);
15             Console.WriteLine("a:"+a+",b:"+b);
16             Console.ReadKey();
17         }

然后以上代碼改為用out實現:

 1         public void yy(int a,int b,out int x,out int y)
 2         {
 3             x = b;
 4             y = a;
 5         }
 6         static void Main(string[] args)
 7         {
 8             Program pg = new Program();
 9             int a = 5;
10             int b = 10;
11             Console.WriteLine("a:" + a + ",b:" + b);
12             pg.yy(a,b,out a,out b);
13             Console.WriteLine("a:"+a+",b:"+b);
14             Console.ReadKey();
15         }

自我感覺吧,在很多地方ref和out可以互換,起到相同的作用,區別僅僅在於ref傳進去的參數必須在調用前初始化,out不必初始化;ref傳進去的參數在函數內部可以直接使用,而out不可以;ref傳進去的參數在函數內部可以不被修改,但out必須在離開函數體前進行賦值。個人感覺ref可以更隨意的使用,out總有那么點別扭,畢竟必須在內部給其賦值。

實習的第一個雙休日

貌似此文扯了些不該扯得,但總的來說都是跟隨筆主要內容有些相關啦,接下來由於培訓內容的相關,得轉移重心了,Linq和EF還得再回去看看,所以后期可能寫點哪方面相關知識。晚睡的習慣還木有改過來,這是個問題得治啊,聽了一晚上的歌,單曲循環"想把我唱給你聽",好晚了,睡覺去也!!!

------如果你覺得此文對你有所幫助,別忘了點擊下右下角的推薦咯,謝謝!------


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM