C# 对象有效
你可以检查一个对象是否为空,但你能检查一个对象是否有效吗?
Assert.IsValid(object_name);
例如,该对象已被垃圾收集器删除或有人对其进行了处理。但指针仍然指向该对象。
You can check if an object is null but can you check if an object is valid?
Assert.IsValid(object_name);
For example, the object has been deleted by the garbage collector or someone has done dispose on it. But the pointer is still pointing to that object.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
如果该对象已被垃圾收集器释放,那么根据定义,您将不会拥有对它的引用。
如果它已被处理并且这对于对象的有效性很重要,则该类型应该提供一种确定该情况的方法。 (例如,在某些情况下,
Dispose
只能表示“重置”。)尽管如此,甚至允许引用已处置对象的可能性也是不合适的 - 如果您使用:
则该对象将被在
foo
超出范围的同时进行处理,因此这不是问题。If the object has been freed by the garbage collector, you won't have a reference to it, by definition.
If it's been disposed and that's important to the object's validity, the type ought to provide a way of determining that. (In some cases
Dispose
can just mean "reset", for example.)It's rarely appropriate to even allow the possibility of having a reference to a disposed object though - if you use:
then the object will be disposed at the same time that
foo
goes out of scope, so this isn't an issue.如果该对象已被释放,则没有任何对它的“实时”引用,因此您无法访问它(保证没有可访问的代码可以读/写该对象)(这在“安全”代码中...在“不安全”代码中,没有任何保证,但它是“不安全”的,这是有原因的:-) )
对于
IDisposable
对象,“正确完成”的类保留一个标志:他们检查(bool isDispose = false
在开头,isDispose = true; 在Dispose()
中)在每个方法/属性中,如果对象已经被释放,它们会抛出新的ObjectDisposeException()。
请注意,C# 语言/.NET 运行时中没有任何内容禁止“重新点燃”、重用和再次“重新处置”“已处置”对象,但这是糟糕的代码编写方式(并支持这种“反模式”,甚至还有一个
GC.ReRegisterForFinalize
来平衡通常在Dispose()
中完成的GC.SuppressFinalize
)如果您有一个
WeakReference
并且您想要检查“仅用于统计目的”该对象是否仍然可访问,您可以使用WeakReference.IsValid
。如果您想要使用该对象的引用,请使用WeakReference.Target
并检查返回值是否为null
。这非常重要!If the object has been disposed, there isn't any "live" reference of it, so you can't access it (it's guaranteed that there is no reachable code that can read/write the object) (this in "safe" code... In "unsafe" code there isn't any guarantee of anything. But it's "unsafe" for a reason :-) )
For the
IDisposable
objects, classes "correctly done" keep a flag that they check (bool isDisposed = false
at the beginning, isDisposed = true; in theDispose()
) in every method/property and if the object is already disposed theythrow new ObjectDisposedException()
.Note that there isn't anything in the C# language/.NET runtime that forbids for a "disposed" object to be "reignited", reused and "re-disposed" again, but it is bad code writing (and to support this "anti-pattern" there is even a
GC.ReRegisterForFinalize
to balance theGC.SuppressFinalize
often done inDispose()
)If you have a
WeakReference
and you want to check "only for statistical purpose" if the object is still reachable, you useWeakReference.IsValid
. If you want a reference to the object to use it, you useWeakReference.Target
and check if the return value isnull
. This is very important!!但是如果 object_name 不首先被清空,那么它如何被垃圾回收呢?
如果指针仍然指向该对象(根据您的问题),那么该对象将无法被垃圾收集
but how would object_name get garbage collected if its not nulled first?
If a pointer is still pointing to the object (per your question) then there is no way the object will get garbage collected
将对象存储在 WeakReference 列表中。
使用
IsAlive
属性检查对象是否已被垃圾回收。Store your objects in a list of WeakReference's.
Use the
IsAlive
property to check if the object has been garbage collected.根据定义,垃圾收集器不会删除“非垃圾”对象,其中包括代码所引用的对象。
没有通用的方法来查看对象是否已被释放,因为 IDisposable 合约不包含这样的方法。但许多类都有一种确定其状态的方法,例如,SqlConnection 类有一个 State 属性,它将在已处置的对象上返回 ConnectionState.Closed。
The garbage collector does by definition not delete objects that are "not garbage", that includes objects to which your code holds a reference.
There is no general way to see if an object has been disposed, as the IDisposable contract does not contain such a method. But many classes have a way of determining their state, e.g. the SqlConnection class has a State property which will return ConnectionState.Closed on a disposed object.
就
GC
和自定义对象状态而言,您只能检查对象是否已跨代移动,但无法访问GCed对象或检查对象是否已
Dispose
,因为Dispose()
是每个特定IDisposable
类型的自定义实现,在极少数情况下,这些类型会公开类似 IsDispose 标志的内容,因为它对于对象的使用者没有任何意义大多数情况下。当您知道代号时,您可以根据以下内容进行一些假设:
垃圾基础知识收藏:世代
In terms of
GC
and a custom object state you can only check whether object has been moved across the generations usingbut you can not access GCed object or check whether object was
Disposed
becauseDispose()
is a custom implementation of the each particularIDisposable
type and in very rare cases those types exposed something like IsDisposed flag because it does not make any sense for object's consumer in most cases.When you know a generation number you can do some assumptions based on:
Fundamentals of Garbage Collection: Generations