c#是对象有效的

本文关键字:有效 对象 | 更新日期: 2023-09-27 18:12:28

你可以检查一个对象是否为null,但是你能检查一个对象是否有效吗?

Assert.IsValid(object_name);

例如,对象已被垃圾收集器删除或有人对其进行了dispose处理。但是指针仍然指向那个对象

c#是对象有效的

如果对象已被垃圾回收器释放,那么根据定义,将没有对它的引用。

如果它已被处理,并且这对对象的有效性很重要,则类型应该提供一种确定这一点的方法。(例如,在某些情况下,Dispose可以仅表示"重置"。)

如果使用:

,甚至允许对已处置对象的引用都是不合适的。
using (Foo foo = new Foo())
{
    ...
}

则对象将在foo超出作用域的同时被处置,因此这不是问题。

如果对象已被处置,则没有它的任何"活动"引用,因此您无法访问它(可以保证没有可访问的代码可以读写对象)(这在"安全"代码中…在"不安全"代码中,没有任何保证。但它"不安全"是有原因的:-))

对于IDisposable对象,类"正确完成"保持一个标志,他们检查(bool isDisposed = false在开始,isdispose = 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。

GC和自定义对象状态方面,您只能使用

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

但是你不能访问GCed对象或检查对象是否为Disposed,因为Dispose()是每个特定IDisposable类型的自定义实现,在极少数情况下,这些类型暴露了类似isdispose标志的东西,因为它在大多数情况下对对象的消费者没有任何意义。

当你知道一个代数,你可以做一些假设基于:

垃圾收集基础:世代

0。这是最年轻的一代,包含短寿命对象。短期对象的一个例子是临时对象变量。垃圾收集在其中发生的频率最高的一代。新分配的对象形成新一代对象并且是隐式的第0代集合,除非它们很大对象,在这种情况下,它们被放在一个大的对象堆中第二代收集。大多数对象被回收为垃圾在第0代收集,并且不能存活到下一代。

代1。该代包含短寿命对象,用作短寿命对象和长寿命对象之间的缓冲区。

代2。此代包含长寿命对象。长寿命对象的一个例子是服务器应用程序中的对象包含在流程持续时间内活动的静态数据