简体   繁体   English

字典和OrderedDictionaries的C#通用合并方法

[英]c# generic Merge Method for Dictionaries and OrderedDictionaries

I create the following helper method for merging Dictionaries (overwriting repeating values): 我创建以下合并字典的帮助器方法(覆盖重复的值):

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

I'd like to make it generic so that: 我想使其通用,以便:

  • I can use it with OrderedDictionary 我可以将其与OrderedDictionary一起使用
  • Return the same type of dictionary as source 返回与源相同类型的字典

Any idea how to achieve it or any other improvement to my function? 知道如何实现它或对我的功能进行任何其他改进吗?

I can think of a few ways ( none of them really great ) 我可以想到几种方法(它们都不是很好的方法)

1) If you don't mind modifying the source dictionary, just add to it and return it, instead of doing new Dictionary 1)如果您不介意修改源词典,则只需添加并返回源词典,而不用做新的词典

2) If the caller knows the concrete dictionary type, you can call the generic method explicitly and tell it what type to return or: 2)如果调用者知道具体的字典类型,则可以显式调用泛型方法并告诉其返回哪种类型,或者:

3) You can use a generic class on the concrete type 3)您可以在具体类型上使用泛型类

4) Instead of using the dictionary classes directly, derive from them and make them ICloneable. 4)不是直接使用字典类,而是从它们派生并使其可克隆。 Then use clone instead of new dictionary 然后使用克隆代替新字典

EDIT: 编辑:

For option #2, I discovered that you don't really need explicit generic calls, explicit casts will be enough. 对于选项2,我发现您实际上不需要显式泛型调用,显式强制转换就足够了。 You could have code like this: 您可能会像这样的代码:

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

Here are some notes: 这里有一些注意事项:

1) You have to use the non-generic System.Collections.IDictionary as the parameter type. 1)您必须使用非通用的System.Collections.IDictionary作为参数类型。 Its the common one to Dictionary and OrderedDictionary because OrderedDictionary is not a generic type 这是Dictionary和OrderedDictionary的共同点,因为OrderedDictionary不是通用类型

2) To do a new on T,and force it to only be IDictionaries you have to add the where clause 2)要在T上做一个新的,并将其强制为IDictionaries,则必须添加where子句

3) If you don't have the variables for the two inputs declared as concrete types, but only have their interfaces, things get ugly, and then you need explicit casting ( shown below ). 3)如果您没有两个声明为具体类型的输入的变量,而只有它们的接口,情况就会变得很糟,那么您需要进行显式转换(如下所示)。 In this case , it may be better to chose option #5 and just have the caller pass the target container they would like as a third parameter 在这种情况下,最好选择选项#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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM