C # глубокое / вложенное / рекурсивное слияние динамических / расширяемых объектов

Мне нужно «слить» 2 динамических объекта в C #. Все, что я нашел на stackexchange, касалось только нерекурсивного слияния. Но я ищу что-то рекурсивное или глубокое слияние, очень похожее на функцию jQuery $. Extend (obj1, obj2) .

При столкновении двух членов должны применяться следующие правила:

  • Если типы не совпадают, должно быть сгенерировано исключение и слияние прерывается. Исключение: obj2 Значение может быть нулевым, в этом случае используется значение и тип obj1.
  • Для тривиальных типов (типы значений + строка) всегда предпочтительны значения obj1
  • Для нетривиальных типов применяются следующие правила:
    • IEnumerable и IEnumberables просто объединяются (возможно, .Concat () ?)
    • IDictionary & IDictionary объединены; ключи obj1 имеют приоритет при столкновении
    • Expando & Типы Expando [] должны быть объединены рекурсивно, тогда как Expando [] всегда будет иметь только элементы одного типа
    • Можно предположить, что нет Объекты Expando в коллекциях (IEnumerabe и IDictionary)
  • Все другие типы могут быть отброшены и не должны присутствовать в результирующем динамическом объекте

Вот пример возможного слияния:

dynamic DefaultConfig = new {
    BlacklistedDomains = new string[] { "domain1.com" },
    ExternalConfigFile = "blacklist.txt",
    UseSockets = new[] {
        new { IP = "127.0.0.1", Port = "80"},
        new { IP = "127.0.0.2", Port = "8080" }
    }
};

dynamic UserSpecifiedConfig = new {
    BlacklistedDomain = new string[] { "example1.com" },
    ExternalConfigFile = "C:\\my_blacklist.txt"
};

var result = Merge (UserSpecifiedConfig, DefaultConfig);
// result should now be equal to:
var result_equal = new {
    BlacklistedDomains = new string[] { "domain1.com", "example1.com" },
    ExternalConfigFile = "C:\\my_blacklist.txt",
    UseSockets = new[] {
        new { IP = "127.0.0.1", Port = "80"},
        new { IP = "127.0.0.2", Port = "8080" }
    }
};

Есть идеи, как это сделать?

8
задан Dynalon 27 January 2012 в 17:10
поделиться