2017-04-06 101 views
0

創建欄時,我使用TypeBuilder創建類型。這些類型然後用作泛型類中的參數。我想要做的是從它的名字創建Type。通用參數是動態的事實似乎是一個障礙。檢索Foo類型<Bar>從TypeBuilder

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); // This succeeds. Replacing 'int' with a Type defined in another project also works 
    } 

    // This is the essence of what I want to do 
    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(); 
    } 
} 

很明顯,我知道如何從MakeGenericType創建Type,但我一起工作的實際生活的場景,我不想(或不能)裂傷類型名稱,以便我能分別創建類型並將它們組合在一起。

我怎樣才能重現這種Typestring名字?

+1

那麼,您生成的類型生活在您稱爲'DynamicAssembly'的程序集中,對嗎?那麼你爲什麼在_executing_程序集中尋找它? –

+0

'Generic <>'住在正在執行的程序集中。從執行裝配工作中檢索'Generic '。 (檢索'通用''從DynamicAssembly'不工作 - 我沒有嘗試) – AbleArcher

+0

檢索''從'從ExecutingAssembly' DynamicAssembly'和'通用<>'DynamicType'(或只是'typeof'如果你知道'通用<>'靜態)。然後使用'MakeGenericType'將它們放在一起。 –

回答

0

它發生,我認爲我應該使用拋出出錯的Exception的的Assembly.GetType()版本。它拋出一個FileNotFoundException,顯然,在通用參數中,只允許來自文件的程序集。爲了解決這個問題,我註冊了來自AppDomainAssemblyResolve事件,並處理了文件中未找到DynamicAssembly的情況。我的工作代碼:

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; 
    } 

    // This is the essence of what I want to do 
    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(); 
    } 
相關問題