Пытаюсь понять реализацию WeakReference от Microsoft

Как опытный программист C++, пытающийся освоиться в .NET, меня беспокоит одна деталь реализации свойства WeakReference "Target" от Microsoft...

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? Особенно в методе 'set' - использование GC.KeepAlive в конце метода должно удерживать WeakReference от сборки мусора, и таким образом сохранять хэндл ненулевым - верно?

А в случае 'get' - как только мы действительно извлекли ссылку на цель через InternalGet, зачем снова проверять исходное значение m_handle? Я могу только предположить, что, возможно, они пытаются защитить WeakReference от утилизации и финализации во время или после InternalGet - но, конечно, не может ли она быть также утилизирована и финализирована до того, как мы вернем объект? Я просто не могу придумать разумного объяснения, зачем нужна эта двойная проверка...

10
задан Kevin 29 December 2011 в 19:16
поделиться