在运行时动态创建类

时间:2014-11-16 12:18:35

标签: vb.net generics reflection dynamic-class

我有一个这样的方法:(这是一种通用的方法,DYNAMIC_CLASS_TYPE将在情况下改为其他情况)

Dim res = f.MyMethod(Of DYNAMIC_CLASS_TYPE)("select Id, Name from myTable")

我想根据查询的列创建一个动态类,然后传递该类而不是DYNAMIC_CLASS_TYPE

我该怎么做?

4 个答案:

答案 0 :(得分:3)

我终于成功了。我的代码如下:

 Public Shared Function CreateClass(ByVal className As String, ByVal properties As Dictionary(Of String, Type)) As Type

    Dim myDomain As AppDomain = AppDomain.CurrentDomain
    Dim myAsmName As New AssemblyName("MyAssembly")
    Dim myAssembly As AssemblyBuilder = myDomain.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.Run)

    Dim myModule As ModuleBuilder = myAssembly.DefineDynamicModule("MyModule")

    Dim myType As TypeBuilder = myModule.DefineType(className, TypeAttributes.Public)

    myType.DefineDefaultConstructor(MethodAttributes.Public)

    For Each o In properties

        Dim prop As PropertyBuilder = myType.DefineProperty(o.Key, PropertyAttributes.HasDefault, o.Value, Nothing)

        Dim field As FieldBuilder = myType.DefineField("_" + o.Key, o.Value, FieldAttributes.[Private])

        Dim getter As MethodBuilder = myType.DefineMethod("get_" + o.Key, MethodAttributes.[Public] Or MethodAttributes.SpecialName Or MethodAttributes.HideBySig, o.Value, Type.EmptyTypes)
        Dim getterIL As ILGenerator = getter.GetILGenerator()
        getterIL.Emit(OpCodes.Ldarg_0)
        getterIL.Emit(OpCodes.Ldfld, field)
        getterIL.Emit(OpCodes.Ret)

        Dim setter As MethodBuilder = myType.DefineMethod("set_" + o.Key, MethodAttributes.[Public] Or MethodAttributes.SpecialName Or MethodAttributes.HideBySig, Nothing, New Type() {o.Value})
        Dim setterIL As ILGenerator = setter.GetILGenerator()
        setterIL.Emit(OpCodes.Ldarg_0)
        setterIL.Emit(OpCodes.Ldarg_1)
        setterIL.Emit(OpCodes.Stfld, field)
        setterIL.Emit(OpCodes.Ret)

        prop.SetGetMethod(getter)
        prop.SetSetMethod(setter)

    Next

    Return myType.CreateType()

End Function

该函数的返回值是我的自定义类的类型。

答案 1 :(得分:2)

似乎有一个错误。我想这一行:

Dim field As FieldBuilder = myType.DefineField("_" + o.Key, GetType(Integer), FieldAttributes.[Private])

应如下所示:

Dim field As FieldBuilder = myType.DefineField("_" + o.Key, o.Value, FieldAttributes.[Private])

问候。

答案 2 :(得分:-1)

更简单的方法是使用System.Activator:

Activator.CreateInstance(YourType, ParramArrayOfYourVariablesForNEW)

所以说我有一个类(Test)在初始化

中占用一个字符串
Public Class Test
    Public Sub New(byval MyString as string)
...

您可以像这样创建一个新实例:

Activator.CreateInstance(gettype(Test),"My String")

答案 3 :(得分:-1)

这一行:

Dim field As FieldBuilder = myType.DefineField("_" + o.Key, GetType(Integer), FieldAttributes.[Private])

必须替换为:

Dim field As FieldBuilder = myType.DefineField("_" + o.Key, o.Value, FieldAttributes.[Private])