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

c#字典和有序字典的通用合并方法

  •  0
  • opensas  · 技术社区  · 6 年前

    public static IDictionary<T1, T2> Merge<T1, T2>(
        IDictionary<T1, T2> source, IDictionary<T1, T2> additional
    ) {
        var result = new Dictionary<T1, T2>(source);
        additional.ToList().ForEach(pair => result[pair.Key] = pair.Value);
        return result;
    }
    

    我想让它通用,这样:

    • 我可以和OrderedDictionary一起使用
    • 返回与源相同类型的字典

    你知道如何实现这一目标,或者对我的工作有什么改进吗?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Gonen I    6 年前

    1) 如果您不介意修改源字典,只需添加到源字典并返回它,而不是执行新字典

    2) 如果调用方知道具体的字典类型,则可以显式调用泛型方法并告诉它要返回的类型,或者:

    3) 可以对具体类型使用泛型类

    4) 与其直接使用dictionary类,不如从dictionary类派生并使其具有可克隆性。然后使用克隆而不是新字典

    编辑:

    对于选项2,我发现其实并不需要显式泛型调用,显式强制转换就足够了。

    namespace ConsoleApp1
    {
        class Program
        {
            public static T Merge<T>( T source, IDictionary additional) where T:IDictionary,new()
            {
                var result = new T();
                foreach (var item in additional.Keys)
                {
                    result.Add(item, additional[item]);
                }
                foreach (var item in source.Keys)
                {
                    result.Add(item, source[item]);
                }
                return result;
            }
    
            static void Main(string[] args)
            {
                OrderedDictionary od = new OrderedDictionary();
                od["A"] = 1;
    
                System.Collections.Generic.Dictionary<String, Int32> dictionary = new System.Collections.Generic.Dictionary<String, Int32>();
                dictionary["B"] = 2;
                IDictionary od2 = Merge(od, dictionary);
                Console.WriteLine("output=" + od2["A"]+od2["B"]+od2.GetType());
                IDictionary dictionary2 = Merge(dictionary, od);
                Console.WriteLine("output=" + dictionary2["A"] + dictionary2["B"] + dictionary2.GetType());
                Console.ReadKey();
            }
        }
    }
    

    以下是一些注意事项:

    1) 你必须使用非通用的System.Collections.IDictionary 作为参数类型。它是Dictionary和OrderedDictionary的常用类型,因为OrderedDictionary不是泛型类型

    2) 要在T上做一个新的操作,并强制它只能是IDictionaries,您必须添加where子句

    3) 如果没有将这两个输入的变量声明为具体类型,但只有它们的接口,事情就会变得难看,然后需要显式转换(如下所示)。在这种情况下,最好选择选项#5,让调用者传递他们想要的目标容器作为第三个参数

        IDictionary od = new OrderedDictionary();
        od["A"] = 1;
        System.Collections.Generic.IDictionary<String, Int32> dictionary = new System.Collections.Generic.Dictionary<String, Int32>();
        dictionary["B"] = 2;
        IDictionary od2 = Merge((OrderedDictionary)od, (System.Collections.Generic.Dictionary<String, Int32>) dictionary);
        Console.WriteLine("output=" + od2["A"]+od2["B"]+od2.GetType());
        IDictionary dictionary2 = Merge((System.Collections.Generic.Dictionary<String, Int32>)dictionary, od);
        Console.WriteLine("output=" + dictionary2["A"] + dictionary2["B"] + dictionary2.GetType());
        Console.ReadKey();