如何在通用方法中使用类生成的动态

时间:2014-12-02 10:04:51

标签: c#

我动态生成了一个类,我想在泛型方法中使用这个类。

如果我可以在项目代码中动态生成类,或者将此类作为Dll添加到我的项目bin文件夹中,并在我的代码中访问它

// This Method Create Class 
var myNewClass = MyTypeBuilder.CompileResultType();

// I Needed To Use This Class In Generic 
List<myNewClass> returnObj = GetData();

// MyTypeBuilder Class Which I Used To Generate Class 

public class MyTypeBuilder
{
    public static void CreateNewObject()
    {
        var myType = CompileResultType();
        var myObject = Activator.CreateInstance(myType);
    }

    static Dictionary<string, Type> _props = new Dictionary<string, Type>() {
            { "Id", typeof(string) },
            { "Name", typeof(string) },
            /*{ "ProductLists", typeof(string[]) }*/
        };

    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 _props)
            CreateProperty(tb, field.Key, field.Value);

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

1 个答案:

答案 0 :(得分:0)

尝试List<dynamic> returnObj = GetData();

通用类型参数在编译时解析,因此无法使用在运行时动态构造的类型作为参数。

你可以使用dynamic解决这个问题,但我不知道为什么你可以使用动态来完全需要运行时类型构建器。

在您提供的示例中,您可能只需要一个简单的var returnObj = GetData();