c# - How to make .NET reflection to work with dynamically generated objects? -
this question has answer here:
look @ following example:
void main() { // approach 1: anonymous type var myobject = new { property1 = "propertyvalue1" }; // works: properties contains "property1" var properties = myobject.gettype().getproperties(); // approach 2: expando object dynamic myobject2 = new expandoobject(); myobject2.property1 = "propertyvalue1"; // not work: properties2 null or empty var properties2 = myobject2.gettype().getproperties(); }
what want make type.getproperties()
work on dynamically generated type. understand why works in approach 1 , not 2. actually, in approach 1, compiler has oportunity generate anonymous type looks named type. in approach 2, however, compile time type expandoobject, reflection doesn't work properly.
how create runtime object, dynamic , work reflection, getproperties
method?
edit
thanks answers, understand , know how keys , values expandoobject.. problem need pass dynamically created instance method, outside control will, in turn, call getproperties() on instance.
in order values via reflection dynamically-constructed type, you'll need use reflection.emit
. less ideal requires emit msil. if use case requires simple property access, may feasible, though ill-advised.
here's simple, lightly-tested, type builder uses reflection.emit
:
public static class typebuilderutil { public static type builddynamictype() { var typebuilder = createtypebuilder( "dynamictype" ); createproperty( typebuilder, "property1", typeof ( string ) ); var objecttype = typebuilder.createtype(); return objecttype; } private static typebuilder createtypebuilder( string typename ) { var assemblybuilder = appdomain.currentdomain.definedynamicassembly( new assemblyname( "dynamicassembly" ), assemblybuilderaccess.run ); var modulebuilder = assemblybuilder.definedynamicmodule( "dynamicmodule" ); var typebuilder = modulebuilder.definetype( typename, typeattributes.public | typeattributes.class | typeattributes.autoclass | typeattributes.ansiclass | typeattributes.beforefieldinit | typeattributes.autolayout , null ); return typebuilder; } private static void createproperty( typebuilder typebuilder, string propertyname, type propertytype ) { var backingfieldbuilder = typebuilder.definefield( "_" + propertyname, propertytype, fieldattributes.private ); var propertybuilder = typebuilder.defineproperty( propertyname, propertyattributes.hasdefault, propertytype, null ); // build setter var gettermethodbuilder = typebuilder.definemethod( "get_" + propertyname, methodattributes.public | methodattributes.specialname | methodattributes.hidebysig, propertytype, type.emptytypes ); var getteril = gettermethodbuilder.getilgenerator(); getteril.emit( opcodes.ldarg_0 ); getteril.emit( opcodes.ldfld, backingfieldbuilder ); getteril.emit( opcodes.ret ); // build setter var settermethodbuilder = typebuilder.definemethod( "set_" + propertyname, methodattributes.public | methodattributes.specialname | methodattributes.hidebysig, null, new[] {propertytype} ); var setteril = settermethodbuilder.getilgenerator(); setteril.emit( opcodes.ldarg_0 ); setteril.emit( opcodes.ldarg_1 ); setteril.emit( opcodes.stfld, backingfieldbuilder ); setteril.emit( opcodes.ret ); propertybuilder.setgetmethod( gettermethodbuilder ); propertybuilder.setsetmethod( settermethodbuilder ); } }
you create type, populate such:
var mytype = typebuilderutil.builddynamictype(); var myobject = activator.createinstance( mytype ); // set value var propertyinfo = myobject.gettype().getproperty( "property1", bindingflags.instance | bindingflags.public ); propertyinfo.setvalue( myobject, "propertyvalue", null );
Comments
Post a Comment