如何在泛型方法中使用类生成的动态
本文关键字:动态 泛型方法 | 更新日期: 2023-09-27 18:32:42
我动态生成了一个类,我想在泛型方法中使用这个类。
如果我可以在我的项目代码中动态生成类,或者将此类作为 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);
}
}
尝试List<dynamic> returnObj = GetData();
泛型类型参数在编译时解析,因此不能将运行时动态构造的类型用作参数。
您可以使用动态来解决这个问题,尽管我不确定如果您可以使用动态,为什么您需要运行时类型生成器。
在您提供的示例中,您可能只需要一个简单的var returnObj = GetData();
。