作为一名经验丰富的C ++程序员,他试图熟悉.NET,而且还有微软的WeakReference" Target"那些困扰我的财产......
public class WeakReference : ISerializable
{
internal IntPtr m_handle;
internal bool m_IsLongReference;
...
public virtual object Target
{
[SecuritySafeCritical]
get
{
IntPtr handle = this.m_handle;
if (IntPtr.Zero == handle)
{
return null;
}
object result = GCHandle.InternalGet(handle);
if (!(this.m_handle == IntPtr.Zero))
{
return result;
}
return null;
}
[SecuritySafeCritical]
set
{
IntPtr handle = this.m_handle;
if (handle == IntPtr.Zero)
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized"));
}
object oldValue = GCHandle.InternalGet(handle);
handle = this.m_handle;
if (handle == IntPtr.Zero)
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized"));
}
GCHandle.InternalCompareExchange(handle, value, oldValue, false);
GC.KeepAlive(this);
}
}
...
}
让我烦恼的是这个 - 他们为什么要两次检查m_handle的有效性?特别是在'设置'方法 - 在方法结束时使用GC.KeepAlive应该保持WeakReference不被垃圾收集,从而使句柄保持非零 - 对吗?
对于' get' - 一旦我们通过InternalGet实际检索到对目标的引用,为什么还要再次检查原始m_handle值?我能想到的可能是他们可能会在内部获取期间或之后试图防止WeakReference被处理和最终确定 - 但是在我们到处返回之前,它也无法被处理和最终确定。宾语?我不能提出有效的解释,为什么这里需要进行这种复核......
答案 0 :(得分:8)
我所能想到的只是他们可能正在努力防范 WeakReference在处理期间或之后处理和完成 InternalGet
这是完全正确的。
但可以肯定的是,它也不能被处理和最终确定 在我们开始返回对象之前?
不,因为在那时,必须为对象创建一个强指针。 InternalGet
返回一个强指针,如果存储在oldValue
中的强指针指向对象,则垃圾收集器现在无法再回收该对象。