2011-10-27 30 views
2

您可以檢查一個對象是否爲空,但是可以檢查一個對象是否有效?C#對象有效

Assert.IsValid(object_name); 

例如,該對象已被垃圾回收器刪除或某人已經完成處置。但指針仍然指向該對象。

回答

7

如果對象已被垃圾收集器釋放,那麼將不會有的引用。

如果它被丟棄並且對對象的有效性很重要,那麼類型應該提供一種確定方法。 (在某些情況下Dispose可能僅僅意味着「復位」,例如。)

這是很少適當甚至允許有一個釋放的對象的引用的可能性,雖然 - 如果你使用:

using (Foo foo = new Foo()) 
{ 
    ... 
} 

然後該對象將在foo超出範圍的同時處理,因此這不是問題。

0

將您的對象存儲在WeakReference的列表中。

使用IsAlive屬性檢查對象是否被垃圾收集。

2

如果該對象已被處置,則它沒有任何「活動」引用,因此您無法訪問它(它保證沒有可訪問的代碼可以讀/寫對象)(在「安全」代碼...在「不安全」的代碼中沒有任何保證,但它是「不安全的」,原因是:-))

對於IDisposable對象,類「正確完成」他們在每個方法/屬性中檢查(bool isDisposed = false開頭,isDisposed = true;在Dispose()),並且如果該對象已經處理完畢,則它們爲throw new ObjectDisposedException()

請注意,C#語言/ .NET運行時中沒有任何內容禁止「處置」對象再次「重新點火」,重新使用和「重新處置」,但這是錯誤的代碼寫入支持這個「反模式」甚至有一個GC.ReRegisterForFinalize平衡GC.SuppressFinalize經常Dispose()完成)

如果你有一個WeakReference並且要檢查「只作統計用途」如果對象仍然可以到達,你使用WeakReference.IsValid。如果要引用該對象以使用它,請使用WeakReference.Target並檢查返回值是否爲null。這個非常重要!!

var wr = new WeakReference(new List<int>()); 

// Right!! 
var target = (List<int>)wr.Target; 
if (target != null) 
{ 
    target.Clear(); 
} 

// Wrong!! The GC could kick in after the if and before the target = 
if (wr.IsAlive) 
{ 
    target = (List<int>)wr.Target; 
    target.Clear(); 
} 
0

垃圾回收器按照定義不會刪除「非垃圾」對象,其中包含代碼將引用保存到的對象。

由於IDisposable協定中沒有包含此類方法,因此沒有一種常規方法可以查看是否已放棄對象。但是許多班級都有確定其狀態的方式,例如, SqlConnection類有一個State屬性,它將在一個已處理的對象上返回ConnectionState.Closed。

1

但是如果object_name不先被清零,object_name會如何收集垃圾回收?

如果指針依然指向的對象(根據您的問題),那麼有沒有辦法的對象會得到垃圾收集

0

GC術語和自定義對象的狀態,你只能檢查對象是否已跨使用

int objectGeneration = GC.GetGeneration(objectInstance) 

幾代移動,但不能訪問GCed對象或檢查對象是否爲Disposed因爲Dispose()是每個特定IDisposable類型公開類似IsDisposed這些類型的,並在極少數情況下,自定義實現因爲它在大多數情況下對於對象的消費者沒有任何意義。

當你知道一個生成編號,你可以做基於一些假設:

Fundamentals of Garbage Collection: Generations

代0這是年輕一代,幷包含短暫的對象。短期對象的一個​​示例是臨時變量 。在這個 世代中垃圾收集最頻繁發生。新分配的對象形成新一代對象 ,並隱含爲第0代集合,除非它們是大的對象,在這種情況下,它們會在第2代集合中繼續使用大對象堆。大多數物體在0代回收垃圾 集合,並且不能存活到下一代。

第1代。這一代包含短命的對象並充當短命對象和長命對象之間的緩衝區。

第2代。這一代包含長壽命的物體。長壽命對象的一個​​示例是服務器應用程序 中的一個對象,其中包含在整個過程中持續存在的靜態數據