プロジェクトに存在しないクラスのインスタンスを動的に作成する C# using System; using System.Reflection; using System.Reflection.Emit; namespace TypeBuilderNamespace { public static class MyTypeBuilder { public static void CreateNewObject() { var myType = CompileResultType(); var myObject = Activator.CreateInstance(myType); } public static Type CompileResultType() { TypeBuilder tb = GetTypeBuilder(); ConstructorBuilder constructor = tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName); // NOTE: assuming your list contains Field objects with fields FieldName(string) and FieldType(Type) foreach (var field in yourListOfFields) CreateProperty(tb, field.FieldName, field.FieldType); Type objectType = tb.CreateType(); return objectType; } private static TypeBuilder GetTypeBuilder() { var typeSignature = "MyDynamicType"; var an = new AssemblyName(typeSignature); AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule"); TypeBuilder tb = moduleBuilder.DefineType(typeSignature , TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout , null); return tb; } private static void CreateProperty(TypeBuilder tb, string propertyName, Type propertyType) { FieldBuilder fieldBuilder = tb.DefineField("_" + propertyName, propertyType, FieldAttributes.Private); PropertyBuilder propertyBuilder = tb.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null); MethodBuilder getPropMthdBldr = tb.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes); ILGenerator getIl = getPropMthdBldr.GetILGenerator(); getIl.Emit(OpCodes.Ldarg_0); getIl.Emit(OpCodes.Ldfld, fieldBuilder); getIl.Emit(OpCodes.Ret); MethodBuilder setPropMthdBldr = tb.DefineMethod("set_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, new[] { propertyType }); ILGenerator setIl = setPropMthdBldr.GetILGenerator(); Label modifyProperty = setIl.DefineLabel(); Label exitSet = setIl.DefineLabel(); setIl.MarkLabel(modifyProperty); setIl.Emit(OpCodes.Ldarg_0); setIl.Emit(OpCodes.Ldarg_1); setIl.Emit(OpCodes.Stfld, fieldBuilder); setIl.Emit(OpCodes.Nop); setIl.MarkLabel(exitSet); setIl.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(getPropMthdBldr); propertyBuilder.SetSetMethod(setPropMthdBldr); } } } VB Imports System Imports System.Reflection Imports System.Reflection.Emit Public NotInheritable Class CustomType Private Sub New() End Sub Public Shared Function CreateNewObject() Dim myType = CompileResultType() Dim myObject = Activator.CreateInstance(myType) Return myObject End Function Public Shared Function CompileResultType() As Type Dim tb As TypeBuilder = GetTypeBuilder() Dim constructor As ConstructorBuilder = tb.DefineDefaultConstructor(MethodAttributes.[Public] Or MethodAttributes.SpecialName Or MethodAttributes.RTSpecialName) ' MyObjectInstanceは動的にクラスインスタンスを作成するため、必須な情報を格納している For Each col As MyObjectType In MyObjectInstance CreateProperty(tb, col.colName, GetType(String)) Next Dim objectType As Type = tb.CreateType() Return objectType End Function Private Shared Function GetTypeBuilder() As TypeBuilder Dim typeSignature = "MyDynamicType" Dim an = New AssemblyName(typeSignature) Dim assemblyBuilder As AssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run) Dim moduleBuilder As ModuleBuilder = assemblyBuilder.DefineDynamicModule("MainModule") Dim tb As TypeBuilder = moduleBuilder.DefineType(typeSignature, TypeAttributes.[Public] Or TypeAttributes.[Class] Or TypeAttributes.AutoClass Or TypeAttributes.AnsiClass Or TypeAttributes.BeforeFieldInit Or TypeAttributes.AutoLayout, Nothing) Return tb End Function Private Shared Sub CreateProperty(tb As TypeBuilder, propertyName As String, propertyType As Type) Dim fieldBuilder As FieldBuilder = tb.DefineField("_" & propertyName, propertyType, FieldAttributes.Private) Dim propertyBuilder As PropertyBuilder = tb.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, Nothing) Dim getPropMthdBldr As MethodBuilder = tb.DefineMethod(propertyName, MethodAttributes.Public Or MethodAttributes.SpecialName Or MethodAttributes.HideBySig, propertyType, Type.EmptyTypes) Dim getIl As ILGenerator = getPropMthdBldr.GetILGenerator() getIl.Emit(OpCodes.Ldarg_0) getIl.Emit(OpCodes.Ldfld, fieldBuilder) getIl.Emit(OpCodes.Ret) Dim setPropMthdBldr As MethodBuilder = tb.DefineMethod(propertyName, MethodAttributes.Public Or MethodAttributes.SpecialName Or MethodAttributes.HideBySig, Nothing, New Type() {propertyType}) Dim setIl As ILGenerator = setPropMthdBldr.GetILGenerator() Dim modifyProperty As Label = setIl.DefineLabel() Dim exitSet As Label = setIl.DefineLabel() setIl.MarkLabel(modifyProperty) setIl.Emit(OpCodes.Ldarg_0) setIl.Emit(OpCodes.Ldarg_1) setIl.Emit(OpCodes.Stfld, fieldBuilder) setIl.Emit(OpCodes.Nop) setIl.MarkLabel(exitSet) setIl.Emit(OpCodes.Ret) propertyBuilder.SetGetMethod(getPropMthdBldr) propertyBuilder.SetSetMethod(setPropMthdBldr) End Sub End Class 月額たった 1,050円で始められる本格的なお店のホームページ! コメント: |