C#是对象有效的

时间:2011-10-27 11:56:58

标签: c# pointers

您可以检查对象是否为null,但是您可以检查对象是否有效吗?

Assert.IsValid(object_name);

例如,垃圾收集器已删除该对象,或者某人已对其进行了处置。但指针仍指向该对象。

6 个答案:

答案 0 :(得分:7)

如果对象已被垃圾收集器释放,那么根据定义将不会引用它。

如果它被处理掉并且对于对象的有效性很重要,那么这种类型应该提供一种确定它的方法。 (例如,在某些情况下,Dispose只能表示“重置”。)

即使允许引用已处置对象的可能性,也很少适用 - 如果您使用:

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

然后该对象将在foo超出范围的同时处理,因此这不是问题。

答案 1 :(得分: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();
}

答案 2 :(得分:1)

但是如果object_name首先没有被清空,它将如何收集垃圾?

如果指针仍指向对象(根据您的问题),那么对象将无法收集垃圾

答案 3 :(得分:0)

将您的对象存储在WeakReference的列表中。

使用IsAlive属性检查对象是否已被垃圾回收。

答案 4 :(得分:0)

根据定义,垃圾收集器不会删除“非垃圾”的对象,包括代码保存引用的对象。

由于IDisposable合同不包含此类方法,因此无法查看是否已处置对象。但是许多班级都有办法确定他们的状态,例如: SqlConnection类有一个State属性,它将在已处置的对象上返回ConnectionState.Closed。

答案 5 :(得分:0)

GC和自定义对象状态而言,您只能使用

检查对象是否已在代数中移动
int objectGeneration = GC.GetGeneration(objectInstance)

但您无法访问GCed对象或检查对象是否为Disposed,因为Dispose()是每种特定IDisposable类型的自定义实现,并且在极少数情况下,这些类型会暴露出类似IsDisposed标志,因为在大多数情况下它对对象的消费者没有任何意义。

当您知道世代号时,您可以根据以下内容做一些假设:

Fundamentals of Garbage Collection: Generations

  

第0代。这是最年轻的一代,包含短期对象。短期对象的一个​​例子是临时的   变量。垃圾收集最常发生在此   代。新分配的对象形成新一代对象   并且是隐式生成0集合,除非它们很大   对象,在这种情况下,它们在一个大的对象堆上   第2代收藏。大多数物体都被回收用于垃圾   在第0代收集并且不能存活到下一代。

     

第1代。此代包含短期对象,并充当短期对象和长期对象之间的缓冲区。

     

第2代。此代包含长寿命对象。长期存在的对象的示例是服务器应用程序中的对象   包含在过程期间有效的静态数据