views:

115

answers:

1

Jquery has utility a function called 'extend' which can be used to merge objects. It is very useful to merge default options with the user specified options , to get the effective options.

Is there any similar function in c#/.Net ?

class settings
{
    public string Directory;
    public string Username;
}
settings default_set = new settings(){ Directory = "C:/" , Username = "admin" };
settings user_set    = new settings(){ Username = "john" };

settings merged      = new settings(){ Directory = "C:/" , Username = "john" };

Is there any way to get the merged data from the two other two objects ? Is there any generic function or I should do some coding using Reflection ?

+1  A: 

I created a similar to the RouteValueDictionary that fulfills this purpose with merge capabilities.

Usage:

var defaultSet = new ParameterDictionary( new { Directory = "C:/", Username = "admin" } );
defaultSet["Username"] = "john"; // contains C:/ and "john"
defaultSet.Merge( new { Directory = "D:/" } ); // contains D:/ and "john"
defaultSet.Merge( new { Directory = "C:/", Username = "admin" } ); // back to original

Implementation:

public class ParameterDictionary : Dictionary<string, object>
{
    public ParameterDictionary()
        : base()
    {
    }

    /// <summary>
    /// Build the parameter dictionary from the public properties of the supplied object
    /// where each key is a property name and each value is the corresponding property's
    /// valuye.
    /// </summary>
    /// <param name="parameters">An object containg the properties making up the initial key/value dictionary state.</param>
    public ParameterDictionary( object parameters )
        : this()
    {
        if (parameters != null)
        {
            if (parameters is IDictionary)
            {
                this.Merge( parameters as IDictionary, true );
            }
            else
            {
                foreach (PropertyInfo info in parameters.GetType().GetProperties())
                {
                    object value = info.GetValue( parameters, null );
                    this.Add( info.Name, value );
                }
            }
        }
    }

    /// <summary>
    /// Merge a dictionary of keys/values with the current dictionary.
    /// </summary>
    /// <param name="dict">The dictionary whos parameters will be added.  Must have string keys.</param>
    /// <param name="replace">True if conflicting parameters should replace the existing ones, false otherwise.</param>
    /// <returns>The updated Parameter dictionary.</returns>
    public ParameterDictionary Merge( IDictionary dict, bool replace )
    {
        foreach (string key in dict.Keys)
        {
            if (this.ContainsKey( key ))
            {
                if (replace)
                {
                    this[key] = dict[key];
                }
            }
            else
            {
                this.Add( key, dict[key] );
            }
        }
        return this;
    }

    /// <summary>
    /// Merge a dictionary of keys/values with the current dictionary.  Replaces conflicting keys.
    /// </summary>
    /// <param name="dict">The dictionary whos parameters will be added.  Must have string keys.</param>
    /// <returns>The updated Parameter dictionary.</returns>
    public ParameterDictionary Merge( object dict )
    {
        return Merge( dict, true );
    }

    /// <summary>
    /// Merge a dictionary of keys/values with the current dictionary.
    /// </summary>
    /// <param name="dict">An object whose properties are used as the new keys/values for the update.</param>
    /// <param name="replace">True if conflicting parameters should replace the existing ones, false otherwise.</param>
    /// <returns>The updated Parameter dictionary.</returns>
    public ParameterDictionary Merge( object dict, bool replace )
    {
        ParameterDictionary newDict = new ParameterDictionary( dict );
        return Merge( newDict, replace );
    }
}
tvanfosson