获取在运行时使用TypeBuilder创建的类的类型

时间:2017-01-07 00:45:02

标签: c# linqpad typebuilder

我有以下代码块,我正在使用TypeBuilder构建一个类(SampleModel)。创建类型后,我尝试使用private static function test(){ //do something } 获取我刚创建的类的Type.GetType。但Type正在返回Type.GetType。这是为什么?

null

namespace TypeBuilderTest { using System; using System.Reflection; using System.Reflection.Emit; class Program { static void Main() { // create a dynamic assembly and module var assemblyName = new AssemblyName("SampleModelAssembly"); var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); var moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name); var runtimeModelType = CreateRuntimeModel(moduleBuilder); var type = Type.GetType(runtimeModelType.AssemblyQualifiedName); // <= This is the call in question. Console.WriteLine("Type: " + type); } static private Type CreateRuntimeModel(ModuleBuilder moduleBuilder) { var modelName = "SampleModel"; // create a new type builder var typeBuilder = moduleBuilder.DefineType( modelName, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Serializable); AddProperty(typeBuilder, "SampleAttribute", typeof(string)); return typeBuilder.CreateType(); } static public void AddProperty(TypeBuilder typeBuilder, string propertyName, Type propertyType) { // Generate a private field FieldBuilder field = typeBuilder.DefineField("_" + propertyName, propertyType, FieldAttributes.Private); // Generate a public property // // The last argument of DefineProperty is null, because the // property has no parameters. (If you don't specify null, you must // specify an array of Type objects. For a parameterless property, // use the built-in array with no elements: Type.EmptyTypes) PropertyBuilder property = typeBuilder.DefineProperty(propertyName, System.Reflection.PropertyAttributes.None, propertyType, null); // The property set and property get methods require a special set of attributes: MethodAttributes GetSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; // Define the "get" accessor method for current private field. MethodBuilder currGetPropMthdBldr = typeBuilder.DefineMethod("get_value", GetSetAttr, propertyType, Type.EmptyTypes); ILGenerator currGetIL = currGetPropMthdBldr.GetILGenerator(); // For an instance property, argument zero is the instance. Load the // instance, then load the private field and return, leaving the // field value on the stack. currGetIL.Emit(OpCodes.Ldarg_0); currGetIL.Emit(OpCodes.Ldfld, field); currGetIL.Emit(OpCodes.Ret); // Define the "set" accessor method for current private field. MethodBuilder currSetPropMthdBldr = typeBuilder.DefineMethod("set_value", GetSetAttr, null, new Type[] { propertyType }); ILGenerator currSetIL = currSetPropMthdBldr.GetILGenerator(); // Load the instance and then the numeric argument, then store the // argument in the field. currSetIL.Emit(OpCodes.Ldarg_0); currSetIL.Emit(OpCodes.Ldarg_1); currSetIL.Emit(OpCodes.Stfld, field); currSetIL.Emit(OpCodes.Ret); // Last, map the "get" and "set" accessor methods to the // PropertyBuilder. The property is now complete. property.SetGetMethod(currGetPropMthdBldr); property.SetSetMethod(currSetPropMthdBldr); } } } 显示runtimeModelType.AssemblyQualifiedName

P.S:当我通过LinqPad运行相同的程序时,间歇性地将类型返回。剩下的时间,我也在那里。

1 个答案:

答案 0 :(得分:2)

通过调用

获取类型类型
assemblyBuilder.GetType (runtimeModelType.FullName)

调用Type.GetType依赖于fusion来定位正确的程序集,我怀疑它可能是不可靠的,因为它是动态创建的。至少,它增加了一层不必要的复杂性。

LINQPad有一个额外的钩子来帮助运行时查找程序集,这可能会让它(有时)工作。