C#程序員請不要混淆引用類型和ref引用傳參


先看一段代碼1:

         static  void Main( string[] args)
        {           
            StringBuilder sb =  new StringBuilder( " 1 ");
            test(sb);
            Console.WriteLine(sb.ToString());
            Console.Read();
        }

         static  void test(StringBuilder sb)
        {
            sb =  new StringBuilder( " 2 ");
        }

錯誤的觀念:

 程序輸出"2",因為StringBuilder是引用類型,函數內部sb變量重新指向了托管堆中的新對象,函數返回后,外部的sb變量也指向了這個新對象,因為是引用類型嗎,我傳的是引用。

 在錯誤的觀念中,認為 “ref引用傳參” 僅對.net中的另一種基本類型——值類型有用。

  這種錯誤觀念通常源於這樣的經驗,看代碼2:

        static  void Main( string[] args)
        {           
            StringBuilder sb =  new StringBuilder( " 1 ");
            test(sb);
            Console.WriteLine(sb.ToString());
            Console.Read();
        }

         static  void test(StringBuilder sb)
        {
            sb.Append( " 2 ");
        }

 我們通常會很自豪的說:“看吧,程序輸出12,這就是引用類型的特點,如果換成值類型就不是了!”。我們得出的結論並沒有錯,實際上,這正是引用類型的特點!然而將這個觀念擴大到代碼1的情況,就錯了!

 正確的理解:

程序正確的輸出是“1”,並沒有因為StringBuilder是引用類型,就應該輸出“2” 。如果要輸出“2”,需要加ref:

        static  void Main( string[] args)
        {           
            StringBuilder sb =  new StringBuilder( " 1 ");
            test(ref sb);
            Console.WriteLine(sb.ToString());
            Console.Read();
        }

         static  void test( ref StringBuilder sb)
        {
            sb =  new StringBuilder( " 2 ");
        }

 

對於ref傳參,只要記住一點:對於值類型來說傳的是值的地址,對於引用類型來說傳的是地址的地址。

對於引用類型,同樣記住一點:引用類型本身的地址是一個值類型。就像我們學習c時,指針本身的地址就是一個int。

好吧,用c來理解c#果然有點拗!直觀的理解:引用類型對象本身不改變,只改變對象的屬性時,我們在操作同一個對象;

如果連對象本身都可能會改變,又要保證在操作同一個對象,就用ref傳引用類型的對象吧!

為什么不用string作測試呢?

因為string對象雖然是引用類型,但不能改變對象的屬性CharArray,每次返回的都是新對象(看起來像值類型,其實不是!)。

        static  void Main( string[] args)
        {           
            String s =  " 1 "
            test(s);
            Console.WriteLine(s);
            Console.Read();
        }

         static  void test(String s)
        {
            s= " 2 ";
        }

程序輸出"1",加 ref后輸出"2"。然而我沒法寫出代碼2了,看來string這個不可變引用類型並不適合作本文的測試,千萬不要認為string是什么混血兒。


免責聲明!

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



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