private int TrimBy <K>(Func <KeyValuePair <T, IValueOrError <R> >, bool> filter, Func <KeyValuePair <T, IValueOrError <R> >, K> selector, Func <K, bool> shouldTrim)
                {
                    var res = 0;

                    for (var node = _lruList.First; node != null; node = node.Next)
                    {
                        var kv = new KeyValuePair <T, IValueOrError <R> >(node.Key, node);

                        if (filter(kv) && shouldTrim(selector(kv)))
                        {
                            LruLinkedList.Remove(ref _lruList, node);
                            _cache.Remove(node.Key);

                            res++;
                        }
                    }

                    return(res);
                }
                private int TrimBy <K>(Func <KeyValuePair <T, IValueOrError <R> >, bool> filter, Func <KeyValuePair <T, IValueOrError <R> >, K> selector, Func <K, bool> shouldTrim)
                {
                    var res = 0;

                    _lock.EnterWriteLock();
                    try
                    {
                        for (var node = _lruList.First; node != null; node = node.Next)
                        {
                            var shouldRemove = false;

                            if (node.Key.TryGetTarget(out T key))
                            {
                                var kv = new KeyValuePair <T, IValueOrError <R> >(key, node);
                                if (filter(kv) && shouldTrim(selector(kv)))
                                {
                                    _cache.Remove(key);
                                    shouldRemove = true;
                                }
                            }
                            else
                            {
                                shouldRemove = true;
                            }

                            if (shouldRemove)
                            {
                                LruLinkedList.Remove(ref _lruList, node);
                                Interlocked.Decrement(ref _count);
                                res++;
                            }
                        }
                    }
                    finally
                    {
                        _lock.ExitWriteLock();
                    }

                    return(res);
                }