代码之家  ›  专栏  ›  技术社区  ›  dlras2

使用Where指定不同的泛型

  •  9
  • dlras2  · 技术社区  · 15 年前

    我在写一封信 bijective dictionary class ,但我想确保这两个泛型类型不是同一类型,原因有两个。

    IDictionary 两个方向的接口,但是

    public class 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
    }
    

    这可能吗?

    词典 ,但我不能保证 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] 会回来的 .

    然而, Jaroslav Jandek's solution TKey键 != t值 TKey键 = t值 加(2,3);加(3,4) 映射单个键 到两个值( 2 在一个方向,和 4 另一方面,)虽然我认为严格来说仍然是一个有效的双射函数。

    4 回复  |  直到 8 年前
        1
  •  3
  •   Jaroslav Jandek    15 年前

    这个怎么样(不同的方法):

    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
    
        2
  •  2
  •   Marc Gravell    15 年前

    简言之,不是。重新优化它,一个选项可能是基于静态初始值设定项的策略,它为相同类型的情况选择适当的具体实现,但不是这样;即

    public class BijectiveDictionary<TKey, TValue>
        : IDictionary<TKey, TValue>
    {
        static readonly ISomeStrategy strategy;
        static BijectiveDictionary() {
            if(typeof(TKey) == typeof(TValue)) {
                strategy = ...
            } else {
                strategy = ...
            }
        }
    }
    

    MakeGenericType

        3
  •  2
  •   Community CDub    8 年前

    在某种程度上,这是可以做到的!我使用区分方法,而不是限定类型的限定符。

    它并不统一,事实上,它可能比它统一要好,因为您可以将单独的接口分开。

    请看我的文章,在另一个上下文中有一个完全有效的例子。 https://stackoverflow.com/a/12361409/471129

    基本上,您要做的是向 IIndexer ,使之成为 IIndexer <TKey, TValue, TDifferentiator> .

    因此,类测试变成: class Test<TKey, TValue> : IIndexer<TKey, TValue, First>, IIndexer<TValue, TKey, Second>

    new Test<int,int>()

    其中第一个和第二个无关紧要:

    interface First { }
    
    interface Second { }
    
        4
  •  -1
  •   Vilx-    15 年前

    即使可以,这段代码的输出是什么?

    var dict = new BijectiveDictionary<int, int>();
    
    dict.Add(2,3);
    dict.Add(3,4);
    
    Console.WriteLine(dict[3]); // Do I get 2 or 4?
    

    也许你可以用另一种不含糊的方式重构你的代码?

    推荐文章