C# 如何创建动态类

C# 如何创建动态类,c#,reflection,C#,Reflection,我试图通过一系列字典生成一个类,代码如下: public static object CreateCustomObject(List<Dictionary<string, string>> fileProperties) { object result = null; // create the assembly and module AssemblyName assemblyName = new AssemblyName();

我试图通过一系列字典生成一个类,代码如下:

public static object CreateCustomObject(List<Dictionary<string, string>> fileProperties)
{
    object result = null;
    
    // create the assembly and module
    AssemblyName assemblyName = new AssemblyName();
    assemblyName.Name = "tmpAssembly";
    AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
    ModuleBuilder module = assemblyBuilder.DefineDynamicModule("tmpAssembly");
    
    // create a new type builder
    TypeBuilder typeBuilder = module.DefineType("CustomObjectToSerialize", TypeAttributes.Public | TypeAttributes.Class);
    
    foreach (Dictionary<string, string> _property in fileProperties)
    {
        foreach (var _elem in _property)
        {
            // create property from file      
            string propertyName = _elem.Key.Replace('.', '_');
            FieldBuilder field = typeBuilder.DefineField("_" + propertyName, typeof(string), FieldAttributes.Private);
            PropertyBuilder property = typeBuilder.DefineProperty(propertyName, PropertyAttributes.None, typeof(string), new Type[] { typeof(string) });
    
            MethodAttributes GetSetAttr = MethodAttributes.Public | MethodAttributes.HideBySig;
    
            MethodBuilder currGetPropMethBldr = typeBuilder.DefineMethod("get_value", GetSetAttr, typeof(string), Type.EmptyTypes);
    
            ILGenerator currGetIL = currGetPropMethBldr.GetILGenerator();
            currGetIL.Emit(OpCodes.Ldarg_0);
            currGetIL.Emit(OpCodes.Ldfld, field);
            currGetIL.Emit(OpCodes.Ret);
    
            MethodBuilder currSetPropMthdBldr = typeBuilder.DefineMethod("set_value", GetSetAttr, typeof(string), Type.EmptyTypes);
    
            ILGenerator currSetIL = currSetPropMthdBldr.GetILGenerator();
            currSetIL.Emit(OpCodes.Ldarg_0);
            currSetIL.Emit(OpCodes.Ldarg_1);
            currSetIL.Emit(OpCodes.Stfld, field);
            currSetIL.Emit(OpCodes.Ret);
    
            property.SetGetMethod(currGetPropMethBldr);
            property.SetSetMethod(currSetPropMthdBldr);
        }
    }
    
    Type generatedType = typeBuilder.CreateType();
    result = Activator.CreateInstance(generatedType);
    PropertyInfo[] properties = generatedType.GetProperties();
    
    int propertiesCount = 0;
    
    List<string> values = new List<string>();
    foreach (Dictionary<string, string> _property in fileProperties)
    {
        foreach (var _elem in _property)
        {
            //values.Add(_elem.Value);
            string value = _elem.Value;
            string propName = _elem.Key.Replace('.', '_');
            PropertyInfo pinfo = generatedType.GetProperty(propName);
            //here I get the error
            //'System.Reflection.TargetParameterCountException' occurred in mscorlib.dll
            pinfo.SetValue(result, value);
            //properties[propertiesCount].SetValue(result, value, null);
            //propertiesCount++;
        }
    }
    
    //values.ForEach(_v =>
    //{
    //   properties[propertiesCount].SetValue(result, _v, null);
    //   propertiesCount++;
    //});
    
    return result;
}
公共静态对象CreateCustomObject(列出文件属性)
{
对象结果=空;
//创建程序集和模块
AssemblyName AssemblyName=新的AssemblyName();
assemblyName.Name=“tmpAssembly”;
AssemblyBuilder AssemblyBuilder=Thread.GetDomain().DefinedDynamicAssembly(assemblyName,AssemblyBuilderAccess.Run);
ModuleBuilder模块=assemblyBuilder.DefinedDynamicModule(“tmpAssembly”);
//创建一个新的类型生成器
TypeBuilder TypeBuilder=module.DefineType(“CustomObjectToSerialize”,TypeAttributes.Public | TypeAttributes.Class);
foreach(fileProperties中的Dictionary\u属性)
{
foreach(属性中的变量元素)
{
//从文件创建属性
字符串propertyName=_elem.Key.Replace('.','');
FieldBuilder field=typeBuilder.DefineField(“\u”+propertyName,typeof(string),FieldAttributes.Private);
PropertyBuilder属性=typeBuilder.DefineProperty(propertyName,PropertyAttributes.None,typeof(string),新类型[]{typeof(string)});
MethodAttributes GetSetAttr=MethodAttributes.Public | MethodAttributes.HideBySig;
MethodBuilder currGetPropMethBldr=typeBuilder.DefineMethod(“get_值”、GetSetAttr、typeof(字符串)、Type.EmptyTypes);
ILGenerator currGetIL=currGetPropMethBldr.GetILGenerator();
currGetIL.Emit(操作码.Ldarg_0);
currGetIL.Emit(操作码.Ldfld,字段);
currGetIL.Emit(操作码Ret);
MethodBuilder currSetPropMthdBldr=typeBuilder.DefineMethod(“set_值”、GetSetAttr、typeof(字符串)、Type.EmptyTypes);
ILGenerator currSetIL=currSetPropMthdBldr.GetILGenerator();
currSetIL.Emit(操作码.Ldarg_0);
currSetIL.Emit(操作码Ldarg_1);
currSetIL.Emit(操作码.Stfld,字段);
currSetIL.Emit(操作码Ret);
SetGetMethod(currGetPropMethBldr);
属性.SetSetMethod(currSetPropMthdBldr);
}
}
类型generatedType=typeBuilder.CreateType();
结果=Activator.CreateInstance(generatedType);
PropertyInfo[]properties=generatedType.GetProperties();
int propertiesCount=0;
列表值=新列表();
foreach(fileProperties中的Dictionary\u属性)
{
foreach(属性中的变量元素)
{
//添加(_elem.Value);
字符串值=_elem.value;
字符串propName=_elem.Key.Replace('.','');
PropertyInfo pinfo=generatedType.GetProperty(propName);
//这里我得到了错误
//mscorlib.dll中出现“System.Reflection.TargetParameterCountException”
pinfo.SetValue(结果、值);
//属性[propertiesCount].SetValue(结果,值,null);
//propertiesCount++;
}
}
//值。ForEach(_v=>
//{
//属性[propertiesCount].SetValue(结果,_v,null);
//propertiesCount++;
//});
返回结果;
}
我在尝试设置属性值时遇到此错误:

mscorlib.dll中发生类型为“System.Reflection.TargetParameterCountException”的未处理异常 其他信息:参数计数不匹配

我检查了样本中的3个属性,我将指定3个值

代码是从


有什么想法吗?

您错误地定义了setter方法。您似乎已从getter复制/粘贴,但没有正确修改返回类型和参数列表

getter返回一个值并且没有参数,setter则不返回值(即is
void
)并接受一个参数

与代码中的内容不同,它应该如下所示:

MethodBuilder currSetPropMthdBldr =
    typeBuilder.DefineMethod("set_value", GetSetAttr, null, new [] { typeof(string) });

为什么不使用ExpandooObject类?我没听说过。你能解释一下吗?Thanks@blacaiExpandoObject是最好的解释和关于我得到的错误?检查这个我应该更好地检查时,键入。