亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術文章
文章詳情頁

ASP.NET堆和棧二之值類型和引用類型的參數傳遞和內存分配

瀏覽:26日期:2022-06-08 14:53:16

".NET的堆和棧"系列:

在" ASP.NET堆和棧一之基本概念和值類型內存分配"中,了解了"堆"和"棧"的基本概念,以及值類型的內存分配。我們知道:當執行一個方法的時候,值類型實例會在"棧"上分配內存,而引用類型實例會在"堆"上分配內存,當方法執行完畢,"棧"上的實例由操作系統自動釋放,"堆"上的實例由.NET Framework的GC進行回收。而本篇的重點要放在:值類型和引用類型參數的傳遞,以及內存分配。

傳遞值類型參數

class Class1{    public void Go()    {int x = 5;AddFive(x); Console.WriteLine(x.ToString());        }         public int AddFive(int pValue)    {pValue += 5;return pValue;    }}

大致過程如下:

1、值類型變量x被放到"棧"上。

2、開始執行AddFive()方法,值類型變量pValue被放到"棧"上,并把x的值賦值給pValue,pValue的值變成了5。

3、繼續執行AddFive()方法,pValue的值變成了10。

4、執行完AddFive()方法,釋放pValue的內存,"棧"指針回到x,線程重新回到Go()方法中。

輸出結果:5

以上,在傳遞值類型參數x的時候,實際上是把x一個字節一個字節地拷貝給pValue。

傳遞容易造成"棧溢出"的值類型參數,在值類型參數前加關鍵字ref

public struct MyStruct{    long a, b, c, d, e, f, g, h, i, j, k, l, m;}public void Go(){    MyStruct x = new MyStruct();    DoSomething(x);}public void DoSomething(MyStruct pValue){    // DO SOMETHING HERE....}

假設以上的值類型struct足夠大,而x和pValue都會被分配到"棧"上,這時可能造成"棧溢出"。

如何避免呢?
--解決辦法是讓DoSomething傳遞一個ref類型參數。這樣寫:

public struct MyStruct{    long a, b, c, d, e, f, g, h, i, j, k, l, m;}public void Go(){    MyStruct x = new MyStruct();    x.a = 5;    DoSomething(ref x);        Console.WriteLine(x.a.ToString());       } public void DoSomething(ref MyStruct pValue){    pValue.a = 12345;}

使用ref后,執行DoSomething(ref x),是把x的地址賦值給了pValue,即pValue和x指向了同一個引用地址。當改變pValue的值,變化也會反映到x中。

輸出結果:12345

以上,為了避免"大型"值類型參數傳遞時造成的"棧溢出",可以在值類型前面加ref關鍵字,于是,在傳遞值類型參數x的時候,實際上是把x本身的棧地址拷貝給pValue,x和pValue指向同一個棧地址。

傳遞引用類型參數

傳遞引用類型參數的道理和在傳遞的值類型參數前面加ref關鍵字是一樣的。

public class MyInt{    public int MyValue;}public void Go(){    MyInt x = new MyInt();    x.MyValue = 2;        DoSomething(x);        Console.WriteLine(x.MyValue.ToString());}public void DoSomething(MyInt pValue){    pValue.MyValue = 12345;}

輸出結果:12345

以上大致過程是這樣:
1、在托管堆上創建一個MyInt類型的實例
2、在棧上創建一個MyInt類型的變量x指向堆上的實例
3、把托管堆上的公共字段MyValue賦值為2
4、通過DoSomething(x)方法,把x的引用地址賦值給pValue,即pValue和x指向同一個引用地址
5、改變pValue的值,也會反映到x上

以上,在傳遞引用類型參數x的時候,實際上是把x指向托管堆實例的引用地址拷貝給pValue,x和pValue指向同一個托管堆實例地址。

傳遞引用類型參數,在引用類型參數之前加關鍵字ref

public class Thing{    } public class Animal:Thing{    public int Weight;} public class Vegetable:Thing{    public int Length;}public void Go(){    Thing x = new Animal();        Switcharoo(ref x);        Console.WriteLine("x is Animal    :   " + (x is Animal).ToString());        Console.WriteLine("x is Vegetable :   " + (x is Vegetable).ToString());} public void Switcharoo(ref Thing pValue){    pValue = new Vegetable();}

輸出結果:
x is Animal : False
x is Vegetable : True

以上大致過程是這樣:
1、在托管堆上創建Animal對象實例。
2、在棧上創建類型為Thing的x變量指向Animal實例的引用地址。
3、通過Switcharoo(ref x)方法把x本身的地址賦值給pValue,至此,pValue和x指向了相同的棧內存地址,任何一方的變化都會反映到另外一方。

4、在Switcharoo(ref Thing pValue)內部,在托管堆上創建Vegetable對象實例。
5、pValue指向Vegetable實例,也就相當于x指向Vegetable實例。

以上,當在引用類型參數之前加上關鍵字ref,再傳遞,是把x本身的棧地址拷貝給pValue,x和pValue指向同一個棧地址。

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對的支持。如果你想了解更多相關內容請查看下面相關鏈接

標簽: ASP.NET
相關文章:
主站蜘蛛池模板: 亚洲一级爽片 | 美美女高清毛片视频黄的一免费 | 国产日韩欧美亚洲综合在线 | 久久在现| 日韩毛片在线免费观看 | 视频二区 调教中字 知名国产 | 激情五月色综合亚洲小说 | 国产合集91合集久久日 | 免费a级毛片在线播放 | 欧美 日韩 中文字幕 | 亚洲综合在线一区 | 欧美日韩亚洲国产千人斩 | 高清成人综合 | 久热中文字幕在线精品首页 | 国产精品1024在线观看免费看 | 精品九九在线 | 在线国产不卡 | 国产va精品网站精品网站精品 | 国产精选在线观看 | 久久久久久久免费视频 | 美女被拍拍拍拍拍拍拍拍 | 亚洲一区二区三区精品影院 | 999久久狠狠免费精品 | 狠狠做久久深爱婷婷97动漫 | 精品一区二区三区在线视频观看 | 成年人小视频在线观看 | 久久91精品国产91久久 | 亚洲国产精品综合久久网络 | 国产一区免费视频 | 精品国产日韩亚洲一区在线 | 国产啪精品视频网给免丝袜 | 午夜国产福利视频一区 | 在线亚洲日产一区二区 | 69欧美xxxxx色护士视频 | 久草视频在线看 | 国产高清在线不卡 | 欧美黄色精品 | 成人免费草草视频 | 成人午夜做爰视频免费看 | 善良的翁熄日本中文字幕1 上海麻豆文化传媒网站入口 | 特黄十八岁大片 |