public WeakReference(ReferenceCountedDisposable <T> reference)
                : this()
            {
                if (reference == null)
                {
                    throw new ArgumentNullException(nameof(reference));
                }

                var instance       = reference._instance;
                var referenceCount = reference._boxedReferenceCount;

                if (instance == null)
                {
                    // The specified reference is already not valid. This case is supported by WeakReference (not
                    // unlike `new System.WeakReference(null)`), but we return early to avoid an unnecessary
                    // allocation in this case.
                    //
                    // ⚠ Note that in cases where referenceCount._weakInstance is already non-null, it would be
                    // possible to reconstruct a strong reference even though the current reference instance was
                    // disposed. This case is intentionally not supported (by checking 'instance' before checking
                    // 'referenceCount._weakInstance'), since it would be confusing semantics if this constructor
                    // sometimes worked from a disposed reference and sometimes did not.
                    return;
                }

                // We only need to allocate a new WeakReference<T> for this reference if one has not already been
                // created for it.
                LazyInitialization.EnsureInitialized(ref referenceCount._weakInstance, static instance => new WeakReference <T>(instance), instance);

                _boxedReferenceCount = referenceCount;
            }
        public IReferenceCountedDisposable <ICacheEntry <TKey, TValue> > GetOrCreate(TKey key, Func <TKey, TValue> valueCreator)
        {
            lock (_gate)
            {
                ReferenceCountedDisposable <Entry> disposable = null;

                // If we already have one in the map to hand out, great
                if (_cache.TryGetValue(key, out var weakReference))
                {
                    disposable = weakReference.TryAddReference();
                }

                if (disposable == null)
                {
                    // We didn't easily get a disposable, so one of two things is the case:
                    //
                    // 1. We have no entry in _cache at all for this.
                    // 2. We had an entry, but it was disposed and is no longer valid. This could happen if
                    //    the underlying value was disposed, but _cache hasn't been updated yet. That could happen
                    //    because the disposal isn't processed under this lock.

                    // In either case, we'll create a new entry and add it to the map
                    disposable  = new ReferenceCountedDisposable <Entry>(new Entry(this, key, valueCreator(key)));
                    _cache[key] = new ReferenceCountedDisposable <Entry> .WeakReference(disposable);
                }

                return(disposable);
            }
        }
            public WeakReference(ReferenceCountedDisposable <T> reference) : this()
            {
                if (reference == null)
                {
                    throw new ArgumentNullException(nameof(reference));
                }

                var instance       = reference._instance;
                var referenceCount = reference._boxedReferenceCount;

                if (instance == null)
                {
                    // The specified reference is already not valid. This case is supported by WeakReference (not
                    // unlike `new System.WeakReference(null)`), but we return early to avoid an unnecessary
                    // allocation in this case.
                    return;
                }

                _weakInstance        = new WeakReference <T>(instance);
                _boxedReferenceCount = referenceCount;
            }