簡體   English   中英

C#是對象有效的

[英]C# is object valid

您可以檢查對象是否為null,但是可以檢查對象是否有效嗎?

Assert.IsValid(object_name);

例如,垃圾收集器已刪除該對象,或者某人已對其進行了處置。 但指針仍然指向該對象。

如果對象已被垃圾收集器釋放,則根據定義,您將不會引用該對象。

如果它被處理掉並且對於對象的有效性很重要,那么類型應該提供一種確定它的方法。 (例如,在某些情況下, Dispose只是意味着“重置”。)

即使允許引用已處置對象的可能性,也很少適用 - 如果您使用:

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

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

如果對象已被釋放,則沒有任何“實時”引用,因此您無法訪問它(保證沒有可讀取/寫入對象的可訪問代碼)(這在“安全”代碼中......在“不安全”代碼中沒有任何保證。但由於某種原因它是“不安全的”:-))

對於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();
}

但是如果object_name首先沒有被收集,它將如何獲取垃圾?

如果指針仍指向對象(根據您的問題),那么對象將無法收集垃圾

將對象存儲在WeakReference列表中。

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

根據定義,垃圾收集器不會刪除“非垃圾”對象,包括代碼保存引用的對象。

由於IDisposable合同不包含這樣的方法,因此沒有通用的方法來查看對象是否已被處置。 但是許多類都有一種確定其狀態的方法,例如SqlConnection類有一個State屬性,它將在已處置的對象上返回ConnectionState.Closed。

GC和自定義對象狀態方面,您只能檢查對象是否已使用代數移動

int objectGeneration = GC.GetGeneration(objectInstance)

但你不能訪問GCed對象或檢查對象是否已被Disposed因為Dispose()是每個特定IDisposable類型的自定義實現,並且在極少數情況下,這些類型暴露了類似IsDisposed標志的東西,因為它對於對象的消費者沒有任何意義。在大多數情況下。

當您知道世代號時,您可以根據以下因素做一些假設:

垃圾收集的基本原理:世代

第0代。這是最年輕的一代,包含短期對象。 短期對象的示例是臨時變量。 垃圾收集在這一代中最常發生。 新分配的對象形成新一代對象,並且隱式生成0集合,除非它們是大對象,在這種情況下它們在第2代集合中的大對象堆上。 大多數對象在第0代被回收用於垃圾收集,並且不能存活到下一代。

第1代。此代包含短期對象,並用作短期對象和長期對象之間的緩沖區。

第2代。這一代包含長壽命的對象。 長期對象的一個​​示例是服務器應用程序中的對象,其中包含在進程持續時間內處於活動狀態的靜態數據

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM