c# - Expression.Convert: Object of type 'System.Int64' cannot be converted to type 'System.Int32' -
i asked question yesterday here reading properties anonymous object , writing them private fields of class. problem solved. here short story:
i have data in json format. deserialize them expandoobject, , pass them idictionary<string, object> method. works fine, except int32 properties. seems change int64, where? don't know.
here method again:
private func<idictionary<string, object>, dynamic> makecreator( type type, expression ctor, ienumerable<propertytofieldmapper> maps) { var list = new list<expression>(); var vlist = new list<parameterexpression>(); // creating new target var targetvariable = expression.variable(type, "targetvariable"); vlist.add(targetvariable); list.add(expression.assign(targetvariable, expression.convert(ctor, type))); // accessing source var sourcetype = typeof(idictionary<string, object>); var sourceparameter = expression.parameter(sourcetype, "sourceparameter"); // calling source containskey(string) method var containskeymethodinfo = sourcetype.getmethod("containskey", new[] { typeof(string) }); var accesssourceindexerprop = sourcetype.getproperty("item"); var accesssourceindexerinfo = accesssourceindexerprop.getgetmethod(); // itrate on writers , add call block var containskeymethodargument = expression.variable(typeof(string), "containskeymethodargument"); vlist.add(containskeymethodargument); foreach (var map in maps) { list.add(expression.assign(containskeymethodargument, expression.constant(map.property.name))); var containskeymethodcall = expression.call(sourceparameter, containskeymethodinfo, new expression[] { containskeymethodargument }); // creating writer var sourcevalue = expression.call(sourceparameter, accesssourceindexerinfo, new expression[] { containskeymethodargument }); var setterinfo = map.field.gettype().getmethod("setvalue", new[] { typeof(object), typeof(object) }); var settercall = expression.call(expression.constant(map.field), setterinfo, new expression[] { expression.convert(targetvariable, typeof(object)), expression.convert(sourcevalue, typeof(object)) }); console.writeline(expression.lambda(settercall)); list.add(expression.ifthen(containskeymethodcall, settercall)); } list.add(targetvariable); var block = expression.block(vlist, list); var lambda = expression.lambda<func<idictionary<string, object>, dynamic>>( block, new[] { sourceparameter } ); return lambda.compile(); } if have this
public class person { public int age { get; set; } public string name { get; set; } } class, , use object
var data = new { name = "amiry", age = 20 }; to initialize instance of person using above method, error occurs:
object of type 'system.int64' cannot converted type 'system.int32'.
but if change age property to:
public long age { get; set; } every thing looks fine , method works perfectly. confused why happens. have idea?
so input dictionary contains long (based on discussion in comments).
the easiest fix add convert.changetype before setvalue.
(passing in sourcevalue , constant(map.field.fieldtype))
however, may have unintended consequence of allowing string -> int conversion.
alternative add own converttype method, decide how types converted.
Comments
Post a Comment