第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

您需要釋放對象并將其設(shè)置為空嗎?

您需要釋放對象并將其設(shè)置為空嗎?

楊魅力 2019-07-08 16:17:23
您需要釋放對象并將其設(shè)置為空嗎?您需要釋放對象并將其設(shè)置為NULL嗎?或者垃圾收集器會在它們超出作用域時清除它們嗎?
查看完整描述

3 回答

?
小唯快跑啊

TA貢獻1863條經(jīng)驗 獲得超2個贊

對象在C#中從不超出作用域,就像它們在C+中所做的那樣。當(dāng)垃圾收集器不再使用時,垃圾收集器會自動處理它們。這是一種比C+更復(fù)雜的方法,在C+中,變量的范圍完全是確定性的。CLR垃圾收集器主動遍歷所有已創(chuàng)建的對象,并計算出它們是否被使用。

對象可以在一個函數(shù)中“超出作用域”,但如果返回其值,則GC將檢查調(diào)用函數(shù)是否保留返回值。

將對象引用設(shè)置為null沒有必要,因為垃圾收集是通過計算其他對象引用的對象來完成的。

在實踐中,你不必擔(dān)心破壞,它只是起作用了,而且很棒:)

Dispose必須對實現(xiàn)的所有對象調(diào)用IDisposable當(dāng)你和他們一起工作完之后。通常您會使用using用這樣的對象阻止:

using (var ms = new MemoryStream()) {
  //...}

編輯在可變范圍內(nèi)。Craig詢問變量范圍是否對象生存期有任何影響。為了正確地解釋CLR的這個方面,我需要從C+和C#中解釋一些概念。

實際變量范圍

在這兩種語言中,變量只能在定義的相同范圍內(nèi)使用-類、函數(shù)或用大括號括起來的語句塊。然而,不同之處在于,在C#中,不能在嵌套塊中重新定義變量。

在C+中,這是完全合法的:

int iVal = 8;//iVal == 8if (iVal == 8){
    int iVal = 5;
    //iVal == 5}//iVal == 8

但是,在C#中,您會得到一個編譯器錯誤:

int iVal = 8;if(iVal == 8) {
    int iVal = 5; //error CS0136: A local variable named 'iVal' cannot be declared in this scope because it would give a
     different meaning to 'iVal', which is already used in a 'parent or current' scope to denote something else}

如果您查看生成的msil-函數(shù)使用的所有變量都是在函數(shù)的開頭定義的,這是有意義的。看看這個函數(shù):

public static void Scope() {
    int iVal = 8;
    if(iVal == 8) {
        int iVal2 = 5;
    }}

下面是生成的IL。注意,在if塊中定義的iVal2實際上是在函數(shù)級別定義的。這實際上意味著,就變量生存期而言,C#只具有類和函數(shù)級別的作用域。

.method public hidebysig static void  Scope() cil managed{
  // Code size       19 (0x13)
  .maxstack  2
  .locals init ([0] int32 iVal,
           [1] int32 iVal2,
           [2] bool CS$4$0000)//Function IL - omitted} // end of method Test2::Scope

C+作用域和對象生存期

每當(dāng)在堆棧上分配的C+變量超出作用域時,它就會被銷毀。請記住,在C+中,您可以在堆?;蚨焉蟿?chuàng)建對象。當(dāng)您在堆棧上創(chuàng)建它們時,一旦執(zhí)行離開范圍,它們就會從堆棧中彈出并被銷毀。

if (true) {
  MyClass stackObj; //created on the stack
  MyClass heapObj = new MyClass(); //created on the heap
  obj.doSomething();} //<-- stackObj is destroyed//heapObj still lives

當(dāng)在堆上創(chuàng)建C+對象時,必須顯式銷毀它們,否則就是內(nèi)存泄漏。但是,堆棧變量沒有這樣的問題。

C#對象生命周期

在CLR中,對象(即引用類型)是在托管堆上創(chuàng)建。對象創(chuàng)建語法進一步加強了這一點??紤]一下這個代碼片段。

MyClass stackObj;

在C+中,這將創(chuàng)建一個MyClass并調(diào)用其默認構(gòu)造函數(shù)。在C#中,它將創(chuàng)建對類的引用MyClass這并不意味著什么。創(chuàng)建類實例的唯一方法是使用new操作員:

MyClass stackObj = new MyClass();

在某種程度上,C#對象非常類似于使用newC+中的語法-它們是在堆上創(chuàng)建的,但與C+對象不同,它們是由運行時管理的,因此您不必擔(dān)心對它們進行析構(gòu)。

因為對象是在堆中,對象引用(即指針)超出作用域的事實變得毫無意義。在確定是否要收集對象時,涉及的因素比簡單地存在對象的引用所涉及的因素更多。

C#對象引用

喬恩·斯基特Java中的對象引用比較連接到氣球上的字符串,氣球是對象。同樣的類比也適用于C#對象引用。它們只是指向包含對象的堆的位置。因此,將其設(shè)置為NULL對象生存期沒有直接影響,氣球繼續(xù)存在,直到GC“彈出”它。

按照氣球的類比,一旦氣球沒有附加條件,它就可以被摧毀,這似乎是合乎邏輯的。事實上,這正是引用計數(shù)對象在非托管語言中的工作方式。但是,這種方法對循環(huán)引用沒有很好的效果。想象一下,兩個氣球由一根繩子連接在一起,但沒有一個氣球與任何其他氣球相連。在簡單的參考計數(shù)規(guī)則下,它們都繼續(xù)存在,即使整個氣球組是“孤兒”。

NET對象很像屋頂下的氦氣氣球。當(dāng)屋頂打開(GC運行)

NETGC使用分代GC和標(biāo)記和掃描的組合。分代方法包括運行時傾向于檢查最近分配的對象,因為它們更可能未使用;標(biāo)記和掃描涉及運行時遍歷整個對象圖,并計算出是否有未使用的對象組。這充分地處理了循環(huán)依賴問題。

此外,.NET GC在另一個線程上運行(即所謂的終結(jié)器線程),因為它有相當(dāng)多的工作要做,在主線程上這樣做會中斷程序。


查看完整回答
反對 回復(fù) 2019-07-08
?
臨摹微笑

TA貢獻1982條經(jīng)驗 獲得超2個贊

就像其他人說的,你絕對想打電話給Dispose如果類實現(xiàn)IDisposable..我對此采取了相當(dāng)強硬的立場。有些人可能會聲稱Dispose在……上面DataSet例如,因為他們拆掉了它,看到它沒有做任何有意義的事情,所以是毫無意義的。但是,我認為這個論點中有很多謬誤。

朗讀,閱讀這,這個值得尊敬的人就這個問題進行有趣的辯論。那就讀讀我的推理這里為什么我認為杰弗里·里克特在錯誤的陣營。

現(xiàn)在,關(guān)于是否應(yīng)該將引用設(shè)置為null..答案是否定的。讓我用下面的代碼來說明我的觀點。

public static void Main(){
  Object a = new Object();
  Console.WriteLine("object created");
  DoSomething(a);
  Console.WriteLine("object used");
  a = null;
  Console.WriteLine("reference set to null");}

那么你認為什么時候被引用的對象a是否有資格領(lǐng)取?如果你說打完電話a = null那你就錯了。如果你說在Main方法完成,那么您也錯了。正確的答案是,它有時有資格領(lǐng)取。期間打電話給DoSomething..這是對的。它有資格以前引用設(shè)置為null甚至在呼吁DoSomething完成。這是因為即使對象引用仍然是根,JIT編譯器也可以識別對象引用何時不再取消引用。


查看完整回答
反對 回復(fù) 2019-07-08
  • 3 回答
  • 0 關(guān)注
  • 543 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號