i creating types using typebuilder
. these types used arguments in generic class. want create type
name. fact generic parameter dynamic seems barrier.
static public class dynamictypetest { public class generic<t> { } static public void test() { type dynamictype = createdynamictype(); type generictype = typeof(generic<>); // generic<dynamictype> type genericdynamictype = generictype.makegenerictype(new type[]{dynamictype}); debug.assert(typefromname(genericdynamictype.fullname) == genericdynamictype); // fail debug.assert(typefromname(genericdynamictype.assemblyqualifiedname) == genericdynamictype); // fail debug.assert(typefromname(genericdynamictype.name) == genericdynamictype); // fail // generic<int> type genericinttype = generictype.makegenerictype(new type[] { typeof(int) }); debug.assert(typefromname(genericinttype.fullname) == genericinttype); // succeeds. replacing 'int' type defined in project works } // essence of want static private type typefromname(string name) { return assembly.getexecutingassembly().gettype(name); } static private type createdynamictype() { assemblyname assemblyname = new assemblyname("dynamicassembly"); assemblybuilder assemblybuilder = appdomain.currentdomain.definedynamicassembly(assemblyname, assemblybuilderaccess.run); modulebuilder modulebuilder = assemblybuilder.definedynamicmodule("dynamicmodule"); typeattributes typeattributes = typeattributes.public | typeattributes.class | typeattributes.autoclass | typeattributes.ansiclass; typebuilder typebuilder = modulebuilder.definetype("dynamictype", typeattributes, typeof(system.object)); return typebuilder.createtype(); } }
obviously know how create type
makegenerictype
, in real-life scenario working with, don't want (or can't) mangle type name can create types separately , piece them together.
how can recreate kind of type
string
name?
it occurred me should use version of assembly.gettype()
throws exception
on error. threw filenotfoundexception
, apparently, in generic arguments, assemblies file allowed. around this, registered assemblyresolve
event appdomain
, , handled case dynamicassembly
not found on file. working code:
static public class dynamictypetest { public class generic<t> { } static public void test() { appdomain.currentdomain.assemblyresolve += currentdomain_assemblyresolve; type dynamictype = createdynamictype(); type generictype = typeof(generic<>); // generic<dynamictype> type genericdynamictype = generictype.makegenerictype(new type[]{dynamictype}); debug.assert(typefromname(genericdynamictype.fullname) == genericdynamictype); // pass appdomain.currentdomain.assemblyresolve -= currentdomain_assemblyresolve; } static assembly currentdomain_assemblyresolve(object sender, resolveeventargs args) { foreach (assembly assembly in appdomain.currentdomain.getassemblies()) { assemblyname assemblyname = assembly.getname(); if (args.name == assemblyname.fullname) { return assembly; } } return null; } // essence of want static private type typefromname(string name) { try { return typeof(generic<>).assembly.gettype(name, true); } catch (exception) { return null; } } static private type createdynamictype() { assemblyname assemblyname = new assemblyname("dynamicassembly"); assemblybuilder assemblybuilder = appdomain.currentdomain.definedynamicassembly(assemblyname, assemblybuilderaccess.run); modulebuilder modulebuilder = assemblybuilder.definedynamicmodule("dynamicmodule"); typeattributes typeattributes = typeattributes.public | typeattributes.class | typeattributes.autoclass | typeattributes.ansiclass; typebuilder typebuilder = modulebuilder.definetype("dynamictype", typeattributes, typeof(system.object)); return typebuilder.createtype(); }
Comments
Post a Comment