c# - How to make a subclass constructor based on a parent class instance? -
i have item , subclass advanceditem (all made of value-types if matters):
public item { public string a; public bool b; public char c; ...// 20 fields } public advanceditem : item { public string z; }
it's easy create item or advanceditem independently:
var item = new item { = "aa", b = true, c = 'c', ... }; var aitem = new advanceditem { = "aa", b = true, c = 'c', ..., z = "zz" };
now, i want turn item advanceditem providing string z separately. in order accomplish thinking of using constructor.
attempt a:
// annoying, not using inheritance of advanceditem:item // need edit whenever alter class item public advanceditem(item item, string z) { = item.a; b = item.b; ...;//many lines z = z; }
attempt b:
// utilize inheritance seems need constructor duplicate public item(item item) { = item.a; b = item.b; ...;//many lines } public advanceditem(item item, string z) : base(item) { z = z; }
is there way improve sec effort avoid writing many lines of x = item.x
? maybe solution auto-clone or auto-duplicate class public item(item item)
wrote in 1 line?
consider using automapper re-create properties between objects.
this allow following:
item = new item { = 3, b = 'a', .... }; advanceditem advanced= mapper.map<advanceditem>(a); string z = "hello world"; advanced.z = z;
update
if not want utilize automapper
can utilize reflection
or better, expressions
. create code bit more complex
consider these 2 types:
class item { public int a, b, c; public string d, e, f; private int privateint; public item(int valueofprivatefield) { privateint = valueofprivatefield; } } class advanceditem : item { public string g; public advanceditem(int valueofprivatefield) : base(valueofprivatefield) { } }
we can define method creates field-wise re-create expression. since mention fields value types can re-create each field 1 1 other object:
private static void mapfields<t>(t target, t source) { type type = typeof (t); if (!mappers.containskey(type)) { //build look re-create fields source target; var targetparam = expression.parameter(typeof(object)); var targetcasted = expression.typeas(targetparam, typeof(t)); var sourceparam = expression.parameter(typeof(object)); var sourcecasted = expression.typeas(sourceparam, typeof(t)); var setters = new list<expression>(); //get non-readonly fields foreach (var fieldinfo in typeof(t).getfields(bindingflags.instance | bindingflags.nonpublic | bindingflags.public).where(f => !f.isinitonly)) { look targetfield = expression.field(targetcasted, fieldinfo); look sourcefield = expression.field(sourcecasted, fieldinfo); setters.add(expression.assign(targetfield, sourcefield)); } look block = expression.block(setters); var mapperfunction = expression.lambda<action<object, object>>(block, targetparam, sourceparam).compile(); mappers[type] = mapperfunction; } mappers[type](target, source); } private static readonly dictionary<type, action<object, object>> mappers = new dictionary<type, action<object, object>>();
this caches functions map fields source target object, , should have close same performance manually writing this.a = a, this.b = b
etc.
calling method:
static void main(string[] args) { var item = new item(56) {a = 5, b = 6}; var advanced = new advanceditem(0); mapfields(advanced, item); int = advanced.a; //5 int b = advanced.b; //6; //note advanced.privateint == 56! }
please note code more complex , less reliable automapper , not recommended or ready production systems.
c# inheritance constructor clone base-class
No comments:
Post a Comment