繁体   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