Пользовательская реализация WeakReference

WeakReference в BCL был разработан в эпоху до создания дженериков, поэтому его интерфейс не так хорош, как мог бы быть. Также свойство IsAlive очень легко использовать неправильно. Если посмотреть на реализацию WeakReference через Reflector, кажется, что мы могли бы реализовать его сами. Вот что я придумал:

    [SecurityPermission(Flags = SecurityPermissionFlag.UnmanagedCode)]
    public sealed class WeakRef<T> where T : class
    {
        private readonly volatile IntPtr _ptr;

        public WeakRef(T target)
            : this(target, false)
        {
        }

        [SecuritySafeCritical]
        public WeakRef(T target, bool trackResurrection)
        {
            var handle = GCHandle.Alloc(target, trackResurrection ? GCHandleType.WeakTrackResurrection : GCHandleType.Weak);
            _ptr = GCHandle.ToIntPtr(handle);
        }

        [SecuritySafeCritical]
        ~WeakRef()
        {
            var ptr = _ptr;
            if ((ptr != IntPtr.Zero) && (ptr == Interlocked.CompareExchange(ref _ptr, IntPtr.Zero, ptr)))
            {
                var handle = GCHandle.FromIntPtr(ptr);
                handle.Free();
            }
        }

        public T Target
        {
            get
            {
                var ptr = _ptr;
                if (IntPtr.Zero != ptr)
                {
                    var target = GCHandle.FromIntPtr(ptr).Target;
                    if (_ptr != IntPtr.Zero)
                    {
                        return (T)target;
                    }
                }
                return null;
            }
        }
    }

но я не уверен, что правильно понял реализацию аналога BCL. Может ли кто-нибудь обнаружить проблемы в приведенном выше коде?

7
задан ubiq 17 August 2011 в 03:38
поделиться