我正在写bijective dictionary class,但是出于两个原因,我想确保两个泛型类型不是同一类型。

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

public class BijectiveDictionary<TKey, TValue>
    : IDictionary<TKey, TValue>, IDictionary<TValue, TKey>

给我“BijectiveDictionary '不能同时实现'IDictionary '和'IDictionary ',因为它们可能会为某些类型参数替换统一”(这是可以理解的,但不是期望的。)

其次,如果两种类型相同,我想写一个优化的解决方案。
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
}

这可能吗?

如果没有,我可以考虑不实现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);
    }
}

在这种情况下,您无法使用Add(2,3); Add(3,4),因为Add(2,3)也会将3映射到2,并且[3]将返回2

但是,对于TKey!= TValue的情况,Jaroslav Jandek's solution建议使用第二个字典来执行此操作。尽管这在这些情况下效果非常好(以及最终决定实现的目标),但当TKey = TValue时,它并没有完全遵循我的初衷,因为Add(2,3); Add(3,4)可以将单个键3映射到两个值(2 in一个方向,另一个方向是4),尽管我认为严格来说仍然是有效的双射函数。

最佳答案

怎么样(不同的方法):

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;
    }
}

并在代码中:
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

关于c# - 使用何处指定不同的泛型,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3172680/

10-11 10:19