2017-01-07 7 views
1

TypeBuilderを使用してクラス(SampleModel)を構築する次のコードブロックがあります。タイプが作成されたら、今作成したクラスのTypeを得るためにType.GetTypeを使用しようとしています。しかし、Type.GetTypenullです。どうしてこれなの?TypeBuilderを使用してランタイム中に作成されたクラスの型を取得する

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.AssemblyQualifiedNameSampleModel, SampleModelAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null

P.Sを示しています。私はLinqPad経由で同じプログラムを実行すると、断続的に私は戻ってタイプを取得します。残りの時間、私はそこにもnullを取得します。

+0

assemblyBuilder.GetType(runtimeModelType.FullName)を使用すると機能しますか? –

+0

恐ろしい!それはうまくいった!私がLinqPadで試していたType.GetType呼び出しが断続的に動作していた理由を知っていますか?また、あなたのコメントを回答に変えてください。私はそれを受け入れることができます。ありがとう! – pmohandas

+0

また、Type.GetType呼び出しが最初に機能しない理由も知っていますか? – pmohandas

答えて

2

Type.GetTypeを呼び出す

assemblyBuilder.GetType (runtimeModelType.FullName) 
を呼び出すことによって、タイプの種類を取得しますが、私はそれが動的に作成されますので、信頼できない可能性が疑われ、正しいアセンブリを配置するために核融合に依存しています。少なくとも、それは不必要な複雑さの層を追加します。

LINQPadには、実行時アセンブリの検索に役立つ追加のフックがあります。これは、(時には)動作させるために役立つかもしれません。

関連する問題