I need to "merge" 2 dynamic objects in C#. All that I've found on stackexchange covered only non-recursive merging. But I am looking to something that does recursive or deep merging, very much the same like jQuery's $.extend(obj1, obj2) function.

Upon collision of two members, the following rules should apply:

  • If the types mismatch, an exception must be thrown and merge is aborted. Exception: obj2 Value maybe null, in this case the value & type of obj1 is used.
  • For trivial types (value types + string) obj1 values are always prefered
  • For non-trivial types, the following rules are applied:
    • IEnumerable & IEnumberables<T> are simply merged (maybe .Concat() ? )
    • IDictionary & IDictionary<TKey,TValue> are merged; obj1 keys have precedence upon collision
    • Expando & Expando[] types must be merged recursively, whereas Expando[] will always have same-type elements only
    • One can assume there are no Expando objects within Collections (IEnumerabe & IDictionary)
  • All other types can be discarded and need not be present in the resulting dynamic object

Here is an example of a possible merge:

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", "e
Edit
Report