亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

C#中的值傳遞和引用傳遞詳細解析

2020-01-24 02:54:35
字體:
來源:轉載
供稿:網友

一、傳遞參數
既可以通過值也可以通過引用傳遞參數。通過引用傳遞參數允許函數成員(方法、屬性、索引器、運算符和構造函數)更改參數的值,并保持該更改。

二、傳遞值類型參數
值類型變量直接包含其數據,這與引用類型變量不同,后者包含對其數據的引用。因此,向方法傳遞值類型變量意味著向方法傳遞變量的一個副本。方法內發生的對參數的更改對該變量中存儲的原始數據無任何影響。如果希望所調用的方法更改參數的值,必須使用 ref 或 out 關鍵字通過引用傳遞該參數。為了簡單起見,下面的示例使用 ref。

1. 通過值傳遞值類型:

復制代碼 代碼如下:

class PassingValByVal
{
static void SquareIt(int x)
// The parameter x is passed by value.
// Changes to x will not affect the original value of x.
{
x *= x;
System.Console.WriteLine("The value inside the method: {0}", x);
}
static void Main()
{
int n = 5;
System.Console.WriteLine("The value before calling the method: {0}", n);

SquareIt(n); // Passing the variable by value.
System.Console.WriteLine("The value after calling the method: {0}", n);
}
}


變量 n 為值類型,包含其數據(值為 5)。當調用 SquareIt 時,n 的內容被復制到參數 x 中,在方法內將該參數求平方。但在 Main 中,n 的值在調用 SquareIt 方法前后是相同的。實際上,方法內發生的更改只影響局部變量 x。

2.通過引用傳遞值類型
下面的示例除使用 ref 關鍵字傳遞參數以外,其余與上一示例相同。參數的值在調用方法后發生更改

復制代碼 代碼如下:

class PassingValByRef
{
static void SquareIt(ref int x)
// The parameter x is passed by reference.
// Changes to x will affect the original value of x.
{
x *= x;
System.Console.WriteLine("The value inside the method: {0}", x);
}
static void Main()
{
int n = 5;
System.Console.WriteLine("The value before calling the method: {0}", n);

SquareIt(ref n); // Passing the variable by reference.
System.Console.WriteLine("The value after calling the method: {0}", n);
}
}


本示例中,傳遞的不是 n 的值,而是對 n 的引用。參數 x 不是 int 類型,它是對 int 的引用(本例中為對 n 的引用)。因此,當在方法內對 x 求平方時,實際被求平方的是 x 所引用的項:n。

3. 交換值類型
更改所傳遞參數的值的常見示例是 Swap 方法,在該方法中傳遞 x 和 y 兩個變量,然后使方法交換它們的內容。必須通過引用向 Swap 方法傳遞參數;否則,方法內所處理的將是參數的本地副本。以下是使用引用參數的 Swap 方法的示例:

復制代碼 代碼如下:

static void SwapByRef(ref int x, ref int y)
{
    int temp = x;
    x = y;
    y = temp;
}

三、傳遞引用類型參數
引用類型的變量不直接包含其數據;它包含的是對其數據的引用。當通過值傳遞引用類型的參數時,有可能更改引用所指向的數據,如某類成員的值。但是無法更改引用本身的值;也就是說,不能使用相同的引用為新類分配內存并使之在塊外保持。若要這樣做,應使用 ref 或 out 關鍵字傳遞參數。為了簡單起見,下面的示例使用 ref。

1. 通過值傳遞引用類型
下面的示例演示通過值向 Change 方法傳遞引用類型的參數 arr。由于該參數是對 arr 的引用,所以有可能更改數組元素的值。但是,試圖將參數重新分配到不同的內存位置時,該操作僅在方法內有效,并不影響原始變量 arr。

復制代碼 代碼如下:

class PassingRefByVal
{
static void Change(int[] pArray)
{
pArray[0] = 888; // This change affects the original element.
pArray = new int[5] {-3, -1, -2, -3, -4}; // This change is local.
System.Console.WriteLine("Inside the method, the first element is: {0}", pArray[0]);
}

static void Main()
{
int[] arr = {1, 4, 5};
System.Console.WriteLine("Inside Main, before calling the method, the first element is: {0}", arr [0]);

Change(arr);
System.Console.WriteLine("Inside Main, after calling the method, the first element is: {0}", arr [0]);
}
}


在上個示例中,數組 arr 為引用類型,在未使用 ref 參數的情況下傳遞給方法。在此情況下,將向方法傳遞指向 arr 的引用的一個副本。輸出顯示方法有可能更改數組元素的內容,在這種情況下,從 1改為 888。但是,在 Change 方法內使用 new 運算符來分配新的內存部分,將使變量 pArray 引用新的數組。因此,這之后的任何更改都不會影響原始數組 arr(它是在 Main 內創建的)。實際上,本示例中創建了兩個數組,一個在 Main 內,一個在 Change 方法內。

2. 通過引用傳遞引用類型
本示例除在方法頭和調用中使用 ref 關鍵字以外,其余與上個示例相同。方法內發生的任何更改都會影響調用程序中的原始變量

復制代碼 代碼如下:

class PassingRefByRef
{
    static void Change(ref int[] pArray)
    {
        // Both of the following changes will affect the original variables:
        pArray[0] = 888;
        pArray = new int[5] {-3, -1, -2, -3, -4};
        System.Console.WriteLine("Inside the method, the first element is: {0}", pArray[0]);
    }

    static void Main()
    {
        int[] arr = {1, 4, 5};
        System.Console.WriteLine("Inside Main, before calling the method, the first element is: {0}", arr[0]);

        Change(ref arr);
        System.Console.WriteLine("Inside Main, after calling the method, the first element is: {0}", arr[0]);
    }
}


方法內發生的所有更改都影響 Main 中的原始數組。實際上,使用 new 運算符對原始數組進行了重新分配。因此,調用 Change 方法后,對 arr 的任何引用都將指向 Change 方法中創建的五個元素的數組。

3. 交換兩個字符串
交換字符串是通過引用傳遞引用類型參數的很好的示例。本示例中,str1 和 str2 兩個字符串在 Main 中初始化,并作為由 ref 關鍵字修改的參數傳遞給 SwapStrings 方法。這兩個字符串在該方法內以及Main 內均進行交換。

復制代碼 代碼如下:

class SwappingStrings
{
static void SwapStrings(ref string s1, ref string s2)
// The string parameter is passed by reference.
// Any changes on parameters will affect the original variables.
{
string temp = s1;
s1 = s2;
s2 = temp;
System.Console.WriteLine("Inside the method: {0} {1}", s1, s2);
}

static void Main()
{
string str1 = "John";
string str2 = "Smith";
System.Console.WriteLine("Inside Main, before swapping: {0} {1}", str1, str2);

SwapStrings(ref str1, ref str2); // Passing strings by reference
System.Console.WriteLine("Inside Main, after swapping: {0} {1}", str1, str2);
}
}


本示例中,需要通過引用傳遞參數以影響調用程序中的變量。如果同時從方法頭和方法調用中移除 ref 關鍵字,則調用程序中不會發生任何更改。

四、引用類型的數據值傳遞(復本傳遞)
類的默認用MemberwiseClone 方法創建一個淺表副本,方法是創建一個新對象,然后將當前對象的非靜態字段復制到該新對象。如果字段是值類型的,則對該字段執行逐位復制。如果字段是引用 類型,則復制引用但不復制引用的對象;因此,原始對象及其復本引用同一對象。深拷貝,即實現ICloneable接口.ICloneable可用于深拷貝 和淺拷貝。這些都是概念,但是需要我們理解:

復制代碼 代碼如下:

   class ClassA : ICloneable
    {
        public string str;
        public SubClass subclass;
        public ClassA()
        {
            str = "classA str";
            subclass = new SubClass();
        }
        //深復制,多層不可用MemberwiseClone()完整實現深復制
        public object Clone()
        {
           // this.a = (string)this.a.Clone();
            //this.b = (B)this.b.Clone();
            var ne = new ClassA();
            ne.str = this.str;
            ne.subclass = (SubClass)this.subclass.Clone(); //this.b的話還是沒有成功
            return ne;
           // return this.MemberwiseClone();
        }
    }

    class SubClass : ICloneable
    {
        public string str;
        public SubClass()
        {
            this.str = "subclass str";
        }
        //深復制,因為只一層,所以可以用MemberwiseClone()方法
        public object Clone()
        {
            this.str = (string)this.str.Clone();
            return this.MemberwiseClone();
        }

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美在线精品免播放器视频| 国产精品美女久久久免费| 5566日本婷婷色中文字幕97| 性色av一区二区咪爱| 欧美激情一级二级| 欧美老少做受xxxx高潮| 久久久久久av| 欧美日韩另类视频| 国产欧美在线看| 日韩av在线不卡| 久久久精品在线观看| 国产精品影片在线观看| 成人有码在线视频| 成年人精品视频| 欧美不卡视频一区发布| 欧美在线精品免播放器视频| 欧美性生交xxxxx久久久| 国产亚洲精品激情久久| 亚洲aⅴ男人的天堂在线观看| 亚洲老板91色精品久久| 久久久久久久久久久久久久久久久久av| 国产精品综合网站| 成人免费午夜电影| 亚洲欧美在线一区| 激情久久av一区av二区av三区| 91精品视频一区| 亚洲香蕉伊综合在人在线视看| 久久久之久亚州精品露出| 日韩视频在线免费| 亚洲精品永久免费精品| 国产精品精品一区二区三区午夜版| 国产精品va在线播放| xvideos成人免费中文版| 日韩av免费在线| 亚洲xxxx3d| 国产91在线视频| 日韩av有码在线| 亚洲精品日韩激情在线电影| 欧美精品性视频| 国产精品扒开腿做爽爽爽男男| 九九九久久久久久| 亚洲免费视频观看| 26uuu国产精品视频| 国产亚洲福利一区| 亚洲最大中文字幕| 成人黄色免费网站在线观看| 亚洲国产欧美日韩精品| 欧美成人中文字幕| 亚洲国产欧美自拍| 欧美精品久久久久久久久久| 欧美高清在线视频观看不卡| 日韩在线中文视频| 92国产精品久久久久首页| 91av视频在线| 国产精品久久久av久久久| 国产小视频91| 在线观看欧美日韩| 国产精品露脸av在线| 欧美专区国产专区| 日韩在线视频二区| 亚洲人在线视频| 亚洲成年网站在线观看| 欧美日韩中文字幕在线| 日韩精品欧美激情| 久久精品人人做人人爽| 亚洲天堂一区二区三区| 97久久精品视频| 久久伊人免费视频| 国产欧美一区二区白浆黑人| 视频在线观看99| 午夜精品久久久久久久男人的天堂| 色www亚洲国产张柏芝| 97av在线影院| 亚洲视频自拍偷拍| 夜夜嗨av色一区二区不卡| 欧美高清视频在线| 国产欧美精品va在线观看| 91久久国产婷婷一区二区| 亚洲曰本av电影| 伊人久久大香线蕉av一区二区| 伊人激情综合网| 亚洲成色www8888| 久久天天躁夜夜躁狠狠躁2022| 美女福利视频一区| 91亚洲精品在线| 国产美女高潮久久白浆| 日韩成人免费视频| 成人av在线天堂| 久久久爽爽爽美女图片| 久久久久久久国产| 国产精品午夜一区二区欲梦| 中文字幕日韩精品有码视频| 91网站在线看| 国内精品小视频在线观看| 国产一区二区三区丝袜| 国产精品国产三级国产专播精品人| 久久资源免费视频| 国产精品高潮视频| 久久久久这里只有精品| 一区二区三区在线播放欧美| 亚洲深夜福利网站| 欧美视频免费在线| 亚洲国产黄色片| 中文字幕亚洲综合久久筱田步美| 一区二区三欧美| 国产精品情侣自拍| 成人午夜激情网| 国产亚洲精品美女久久久久| 欧美怡红院视频一区二区三区| 91精品国产91久久久久福利| 日本一区二区不卡| 国产精品美女主播在线观看纯欲| zzijzzij亚洲日本成熟少妇| 欧美性生交大片免费| 日韩大陆欧美高清视频区| 在线观看欧美日韩国产| 国产福利视频一区二区| 欧美大尺度在线观看| 欧美专区在线观看| 欧美综合一区第一页| 一区二区欧美在线| 成人h片在线播放免费网站| 欧美亚州一区二区三区| 欧美国产亚洲精品久久久8v| 国产在线观看一区二区三区| 亚洲天堂第一页| 一区二区三区视频免费在线观看| 欧美激情亚洲视频| 欧美成人激情视频| 欧美自拍视频在线观看| 成人午夜黄色影院| 欧美中文在线视频| 国产91亚洲精品| 亚洲成年网站在线观看| 色偷偷偷综合中文字幕;dd| 亚洲精品www久久久久久广东| 欧美激情在线观看| 亚洲一区二区三区乱码aⅴ蜜桃女| 欧美精品免费在线观看| 精品人伦一区二区三区蜜桃免费| 色综合久久久888| 久久国产精品久久久| 欧美视频在线观看免费| 久久久av亚洲男天堂| 亚洲美女福利视频网站| 国产欧美久久久久久| 国产成人精品综合| 欧美中文在线字幕| 久久久久国产精品www| 欧美日韩免费在线| 国产精品jvid在线观看蜜臀| 亚洲一区二区三区久久| 在线观看精品自拍私拍| 久热精品视频在线观看| 欧美精品国产精品日韩精品| 日韩在线观看av| 国产精品小说在线| 26uuu另类亚洲欧美日本老年| 91国语精品自产拍在线观看性色| 国产欧美精品一区二区| 精品久久久国产| 亚洲老头同性xxxxx| 综合av色偷偷网| 亚洲欧美日韩一区在线|