c# - Merge two objects in a similar way as to PHP's array_merge -


in php it's common practice pass array options class, , merge array set array holds defaults.

something this.

class myobject {      private static $defaults = array('value'=>10);      private $settings;       public function something(array $settings = array())      {           $this->settings = array_merge(static::defaults,$settings);      } } 

you can in javascript using jquery or other libraries introduce merge function. these scripts let take 2 javascript objects , merge them together. allowing use 1 defaults, , override defaults.

i've found pattern useful, because allows configure large set of defaults assign settings need.

is there anyway in c#?

i write function uses reflection on public properties, thinking must have been done.

edit:

this question has been asked before on stack, not answered in way provides same simplicity can done in php , javascript.

i wasn't able find answer did wanted. wrote small method this. it'll take 2 objects of same time, , merge fields/properties assuming null value represents unassigned field/property.

here usage example. create class hold options communications class, let communication class have defaults , initialize communication user settings.

an example settings class.

public class comsettings {     public int? port;     public string? address;     public bool? keepalive; } 

an example class uses settings in constructor.

public class comlibrary {     private static comsettings _defaults = new comsettings { port = 80, address = "localhost" };      protected comsettings settings;      public comlibrary(comsettings psettings)     {         this.settings = objectmerge<comsettings>(_defaults, psettings);     } } 

this let different classes use comsettings each have different defaults. limitation field/properties have support null assignments.

here's implementation of objectmerge.

    /// <summary>     /// creates new object contains properties of 2 objects merged together.     /// </summary>     /// <typeparam name="t">the class type merge.</typeparam>     /// <param name="pdefaults">instance of defaults object.</param>     /// <param name="psettings">instance of settings object.</param>     /// <returns>a new instance of t merged results.</returns>     public static t objectmerge<t>(t pdefaults, t psettings, bool pmergefields = true, bool pmergeproperties = true) t : class, new()     {         t target = new t();         type type = typeof(t);         list<memberinfo> infos = new list<memberinfo>(type.getmembers());          foreach (memberinfo info in infos)         {             // copy values either defaults or settings             if (pmergefields && info.membertype == membertypes.field)             {                 fieldinfo field = (fieldinfo)info;                 if (field.ispublic)                 {                     object value = field.getvalue(psettings);                     value = (value == null) ? field.getvalue(pdefaults) : value;                     field.setvalue(target, value);                 }             }              // copy values either defaults or settings             if (pmergeproperties && info.membertype == membertypes.property)             {                 propertyinfo prop = (propertyinfo)info;                 if (prop.canwrite && prop.canread)                 {                     object value = prop.getvalue(psettings, null);                     value = (value == null) ? prop.getvalue(pdefaults, null) : value;                     prop.setvalue(target, value, null);                 }             }         }          return target;     } 

and here simple unit test.

/// <summary> ///this test class coreutilstest , intended ///to contain coreutilstest unit tests ///</summary> [testclass()] public class coreutilstest {     /// <summary>     /// class perform testing on.     /// </summary>     public class myclassa     {         public string param1;         public string param2;         public string param3;     }      /// <summary>     /// class perform testing on.     /// </summary>     public class myclassb     {         private string _param1;          public string param1         {             { return _param1; }             set { _param1 = value; }         }         private string _param2;          public string param2         {             { return _param2; }             set { _param2 = value; }         }         private string _param3;          public string param3         {             { return _param3; }             set { _param3 = value; }         }     }      /// <summary>     ///a test setproperties     ///</summary>     [testmethod()]     public void merging_fields()     {         myclassa defaults = new myclassa { param1 = "defaults" };         myclassa settings = new myclassa { param2 = "settings" };         myclassa results = coreutils.objectmerge<myclassa>(defaults, settings);          assert.areequal("defaults", results.param1);         assert.areequal("settings", results.param2);         assert.areequal(null, results.param3);     }      [testmethod()]     public void merging_properties()     {         myclassb defaults = new myclassb { param1 = "defaults" };         myclassb settings = new myclassb { param2 = "settings" };         myclassb results = coreutils.objectmerge<myclassb>(defaults, settings);          assert.areequal("defaults", results.param1);         assert.areequal("settings", results.param2);         assert.areequal(null, results.param3);     }  } 

Comments

Popular posts from this blog

SPSS keyboard combination alters encoding -

Add new record to the table by click on the button in Microsoft Access -

CSS3 Transition to highlight new elements created in JQuery -