使用Where指定不同的泛型

dlr*_*as2 9 .net c# generics

我正在写一个双向字典类,但我想确保两个泛型类型不是同一类型,原因有两个.

首先,我希望它IDictionary在两个方向上实现接口,但是

public class BijectiveDictionary<TKey, TValue>
    : IDictionary<TKey, TValue>, IDictionary<TValue, TKey>
Run Code Online (Sandbox Code Playgroud)

给我"'BijectiveDictionary <TKey,TValue>'不能同时实现'IDictionary <TKey,TValue>'和'IDictionary <TValue,TKey>'因为它们可能统一某些类型参数替换"(这是可以理解的,但不可取的.)

其次,如果两种类型相同,我想编写一个优化的解决方案.

public class BijectiveDictionary<TKey, TValue>
    : IDictionary<TKey, TValue> where TValue : TKey
{
    // Optimized solution
}

public class BijectiveDictionary<TKey, TValue>
    : IDictionary<TKey, TValue>, IDictionary<TValue, TKey> where TValue : !TKey
{
    // Standard solution
}
Run Code Online (Sandbox Code Playgroud)

这可能吗?

如果没有,我可以考虑不实施IDictionary,但我无法保证TValue this[TKey key]并且TKey this[TValue key]会有所不同,这将是不幸的.


看起来这里的问题是当两种类型相同时,会出现特殊情况.

我的原意是要创造出准确映射一个键一个值,反之亦然,这样,每一个字典KeyValuePair<TKey, TValue>(X, Y),一个KeyValuePair<TValue, TKey>(Y, X)同样存在.

TKey=时TValue,这可以简化为单个字典:

public T this[T key]
{
    get { return this[key]; }
    set
    {
        base.Add(key, value);
        base.Add(value, key);
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,你不能Add(2,3); Add(3,4)因为Add(2,3)映射32,[3]并将返回2.

然而,Jaroslav Jandek的解决方案建议使用第二个字典来执行此操作TKey!= TValue.虽然这个奇妙的作品的情形外,(也是我决定实施,到底)它并不完全按照我的原意时TKey= TValue,通过允许Add(2,3); Add(3,4)映射一个键3,以两个值(2在一个方向,并4在另一方面,虽然我认为严格来说仍然是一个有效的双射函数.

Jar*_*dek 3

怎么样(不同的方法):

public class BijectiveDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
    public BijectiveDictionary<TValue, TKey> Reversed { get; protected set; }

    public BijectiveDictionary()
    {
        this.Reversed = new BijectiveDictionary<TValue,TKey>(true);
        this.Reversed.Reversed = this;
    }

    protected BijectiveDictionary(bool reversedWillBeSetFromTheCallingBiji) { }

    protected void AddRaw(TKey key, TValue value)
    {
        base.Add(key, value);
    }

    // Just for demonstration - you should implement the IDictionary interface instead.
    public new void Add(TKey key, TValue value)
    {
        base.Add(key, value);
        this.Reversed.AddRaw(value, key);
    }

    public static explicit operator BijectiveDictionary<TValue, TKey>(BijectiveDictionary<TKey, TValue> biji)
    {
        return biji.Reversed;
    }
}
Run Code Online (Sandbox Code Playgroud)

并在代码中:

BijectiveDictionary<int, bool> a = new BijectiveDictionary<int, bool>();

a.Add(5, true);
a.Add(6, false);

Console.WriteLine(a[5]);// => True
Console.WriteLine(((BijectiveDictionary < bool, int>)a)[true]);// => 5
//or
Console.WriteLine(a.Reversed[true]);// => 5
Run Code Online (Sandbox Code Playgroud)