首頁 > 軟體

C#中引數的傳遞方式詳解

2022-07-31 18:01:38

值型別引數按值傳遞

    class Program 
    { 
        static void Main(string[] args) 
        { 
            int a = 10; 
            Add(a); 
            Console.WriteLine("傳遞之後的值為:" + a); 
            Console.ReadKey(); 
        }
 
        private static void Add(int i) 
        { 
            Console.WriteLine("傳遞之前的值為:" + i); 
            i = i + 10; 
           
        } 
    }

結果:

可見,值型別引數在被方法呼叫的時候,是對本身範例的拷貝和操作,在方法呼叫前後引數值不變。

參照型別引數按值傳遞

當參照型別引數傳遞時,是對託管堆上物件範例內容的操作。
也就是參照型別按值傳遞,傳遞的是參照變數的指標,指向託管堆上的物件範例。

    class Program 
    { 
        static void Main(string[] args) 
        { 
            Student student = new Student(); 
            Add(student); 
            Console.WriteLine("引數傳遞之後的值為:" +student._score); 
            Console.ReadKey(); 
        }
 
 
        private static void Add(Student s) 
        { 
           Console.WriteLine("引數傳遞之前的值為:" + s._score); 
            s._score = 90; 
        } 
    }
 
    public class Student 
    { 
        public int _score = 80; 
    }

結果

可見,參照型別引數在被方法呼叫的時候,是針對變數的參照的操作,一旦參照物件內容發生改變,原來變數的值也隨著改變。

按參照傳遞 ref和out

參照型別引數按值傳遞和按參照傳遞的不同之處:

  • 按值傳遞,傳遞的是引數本身的值,即參照指標。
  • 按參照傳遞,傳遞的是引數的地址,也就是範例指標。

另外,值型別也有按參照傳遞,這時候,傳遞的是值型別的地址。

   class Program 
    { 
        static void Main(string[] args) 
        { 
            int i = 100; 
            string str = "one"; 
            ChangeByValue(ref  i); 
            ChangeByRef(ref str); 
            Console.WriteLine(i); 
            Console.WriteLine(str);
 
            Console.ReadKey(); 
        }
 
        private static void ChangeByValue(ref int iValue) 
        { 
            iValue = 200; 
        }
 
        private static void ChangeByRef(ref string sValue) 
        { 
            sValue = "One more"; 
        } 
    }

可見,不管是值型別,還是參照型別,加入關鍵字ref作為引數,就意味著是對引數地址的操作,即託管堆上範例地址的改變。

另外:

  • 如果需要按參照傳遞,方法的定義和方法的呼叫,都要顯式地使用ref和out。
  • 如果一個方法的引數除了ref和out關鍵字不同,還有其他引數不同,這才構成方法的2個過載。如果僅僅ref和out關鍵字不同,會報錯"...不能僅在ref和out上有差別的過載方法"。

ref和out使用時的不同點:

out告訴編譯器,引數會在方法內部初始化,而在方法之前不需要初始化。

int x;
Foo(out x);

ref告訴編譯器,引數在方法之前必須初始化。

int y = 0;
Foo(ref y);

特殊參照型別string的傳遞

    class Program 
    { 
        static void Main(string[] args) 
        { 
            string str = "Old String"; 
            Console.WriteLine("傳遞之前的值為:" + str); 
            ChangeStr(str); 
            Console.WriteLine("傳遞之後的值為:"+str); 
            Console.ReadKey(); 
        }
 
        private static void ChangeStr(string astr) 
        { 
            astr = "Change String"; 
        } 
    }

結果:

可見,雖然string是參照型別,但按值傳遞的表現和值型別按值傳遞的表現一樣。

總結

  • 參照型別按值傳遞,改變的是參照變數指向的託管堆上物件範例的內容。
  • 參照型別按參照傳遞,改變的是參照變數指向的託管堆上物件範例的地址。

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對it145.com的支援。如果你想了解更多相關內容請檢視下面相關連結


IT145.com E-mail:sddin#qq.com