首页 > 解决方案 > C#两个同类重载之间的双向字典歧义

问题描述

我想创建一个自定义字典,它接受两种数据类型并允许在两个方向上查找(值到键和键到值)。如果有两种不同的数据类型,则该类使用两个不同的字典(OnetoTwo 和 TwotoOne),而如果只有一种数据类型,则使用 OnetoOne。这是我拥有的一些代码:

        public class TwoWayDictionary<T1, T2>
        {
            public Dictionary<T1, T2> OnetoTwo;
            public Dictionary<T2, T1> TwotoOne;
            public Dictionary<T1, T1> OnetoOne;

            public bool Same = false;
            public TwoWayDictionary()
            {
                if (typeof(T1) == typeof(T2))
                {
                    Same = true;
                    OnetoOne = new Dictionary<T1, T1>();
                }
                else
                {
                    OnetoTwo = new Dictionary<T1, T2>();
                    TwotoOne = new Dictionary<T2, T1>();
                }
            }
            public T2 this[T1 key]
            {

                get => Get(key);
                set => Set(key, value);
            }
            public T1 this[T2 key]
            {

                get => Get(key);
                set => Set(value, key);
            }
            public void Add(T1 t1, T2 t2)
            {
                OnetoTwo.Add(t1, t2);
                TwotoOne.Add(t2, t1);
            }
            public void Add(T1 t1, T1 t2)
            {
                OnetoOne.Add(t1, t2);
                OnetoOne.Add(t2, t1);
            }
            public dynamic Get(object T_G)
            {
                if (Same)
                {
                    try
                    {
                        return OnetoOne[(T1)T_G];
                    }
                    catch
                    {
                        return null;
                    }
                }
                else
                {
                    try
                    {
                        return OnetoTwo[(T1)T_G];
                    }
                    catch
                    {
                        try
                        {
                            return TwotoOne[(T2)T_G];
                        }
                        catch { return null; }
                    }
                }
            }

            public void Set(T1 T1_S, T2 T2_S)
            {
               
                try
                {
                    if (!Same)
                    {
                        T1 Test = TwotoOne[T2_S];
                        OnetoTwo.Remove(Test);
                        OnetoTwo.Add(T1_S, T2_S);
                        TwotoOne[T2_S] = T1_S;
                    }
                }
                catch { }

            }
            public void Set(T1 T1_S, T1 T2_S)
            {
                try
                {
                    if (Same)
                    {
                        T1 Test = OnetoOne[T1_S];
                        OnetoOne.Remove(Test);
                        OnetoOne.Add(T2_S, T1_S);
                        OnetoOne[T1_S] = T2_S;
                    }
                }
                catch { }
            }

当我有 2 种不同的数据类型时它工作正常,例如当我有 <int, string> 我可以这样做:

TwoWayDictionary<int, int> TestSame = new TwoWayDictionary<int, int>();
TwoWayDictionary<int, string> TestDiff = new TwoWayDictionary<int, string>();
TestDiff.Add(1, "SomeString"); // This is fine
Console.WriteLine(TestDiff[1]); // This is fine
TestSame.Add(1, 2); // This produces CS0121 (ambiguity)
Console.WriteLine(TestSame[2]); // This produces CS0121 (ambiguity)

但是,当我有两种相同的数据类型时,例如 <int, int> 时,“T1”和“T2”之间存在歧义,这是可以理解的,因为它们都是整数。我想要的是当程序检测到相同数据类型的歧义时,默认为具有相同类型参数的方法,例如public void Add(T1 t1, T1 t2)

标签: c#dictionary

解决方案


最简单的选择是删除所有在类型相同时在内部执行不同操作的代码。只需将数据存储在两个字典中,它就可以正常工作,即使不比您尝试做的更好。

如果实际上有一些令人信服的理由,当类型相同时,您必须拥有一个包含两倍多项目的字典而不是两个字典(我没有看到原因,但如果有一个......)那么创建一个单独的类型,该类型具有单个泛型参数而不是两个,并使用单个内部字典实现,留下如上所述的两种类型版本,在类型相同的情况下无需特殊大小写即可工作。


推荐阅读