加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 自定义WeakReference实现

发布时间:2020-12-15 07:42:46 所属栏目:百科 来源:网络整理
导读:BCL中的WeakReference是在pre-generics时代设计的,所以它的界面并不尽如人意. IsAlive属性也很容易被误用. 查看WeakReference槽Reflector的实现,我们似乎可以自己实现它. 这是我想出的: [SecurityPermission(Flags = SecurityPermissionFlag.UnmanagedCode)
BCL中的WeakReference是在pre-generics时代设计的,所以它的界面并不尽如人意. 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对手.
有人能发现上面代码中的任何问题吗?

解决方法

除了添加错误处理之外,我没有发现任何错误.但是,我更喜欢这个实现的简单性,特别是因为它使用BCL版本而你不必努力“正确”:
public sealed class WeakReference<T> where T : class
{
    public WeakReference(T target) : this(target,trackResurrection)
    {}

    public WeakReference(T target,bool trackResurrection)
    {
        refTarget = new WeakReference(target,trackResurrection);
    }

    public T Target { get { return refTarget.Target as T; } }

    public bool IsAlive { get { return refTarget.IsAlive; }}

    private readonly WeakReference refTarget;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读