Bounded LRU cache backed by LinkedList and Dictionary

C#
using System;
using System.Collections.Generic;

sealed class LruCache<TKey, TValue> where TKey : notnull
{
    private readonly int _cap;
    private readonly Dictionary<TKey, LinkedListNode<(TKey Key, TValue Value)>> _map = new();
    private readonly LinkedList<(TKey Key, TValue Value)> _order = new();
    public LruCache(int cap) => _cap = cap > 0 ? cap : throw new ArgumentOutOfRangeException(nameof(cap));
    public TValue Get(TKey key)
    {
        if (!_map.TryGetValue(key, out var node)) throw new KeyNotFoundException();
        _order.Remove(node); _order.AddFirst(node);
        return node.Value.Value;
    }
    public void Set(TKey key, TValue value)
    {
        if (_map.TryGetValue(key, out var node)) { _order.Remove(node); _map.Remove(key); }
        else if (_map.Count == _cap) { var last = _order.Last!; _order.RemoveLast(); _map.Remove(last.Value.Key); }
        _map[key] = _order.AddFirst((key, value));
    }
}