【问题标题】:c# generic Merge Method for Dictionaries and OrderedDictionariesc#字典和OrderedDictionaries的通用合并方法
【发布时间】:2019-02-20 04:05:41
【问题描述】:

我创建了以下帮助方法来合并字典(覆盖重复值):

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 一起使用
  • 返回与源相同类型的字典

知道如何实现它或对我的功能进行任何其他改进吗?

【问题讨论】:

  • 一个问题,如果一个或两个字典都指定了自定义比较器,您是否也应该支持它?

标签: c# dictionary generics .net-core ordereddictionary


【解决方案1】:

我能想到几种方法(没有一个真的很好)

1) 如果您不介意修改源字典,只需添加并返回即可,而不是新建字典

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

3) 你可以在具体类型上使用泛型类

4) 不要直接使用字典类,而是从它们派生并使其可 ICloneable。然后使用克隆而不是新字典

编辑:

对于选项 #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();

【讨论】:

  • 5) 发送最终字典作为参数(result, source1, source2, ...)
  • @Kalten 是的,当然。
  • 非常感谢,您是否有一些链接可以帮助我开始使用选项 2 和 3?在这些情况下,我不太明白你的意思。
  • 优秀的答案@Gonen I ,我希望我能给你更多的选票。这是我第一次看到T:new() 的东西
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-22
  • 1970-01-01
  • 2018-04-16
  • 1970-01-01
相关资源
最近更新 更多