我正在尝试使用以下代码通过词典列表生成一个类dinamicaly:
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;
}
尝试设置属性值时出现此错误。:
类型为&#39; System.Reflection.TargetParameterCountException&#39;的未处理异常发生在mscorlib.dll中 附加信息:参数计数不匹配。
我检查过,我的样本中有3个属性,我将分配3个值。
代码被采用并且稍微改编自here
有什么想法吗?
答案 0 :(得分:1)
您已错误地定义了setter方法。您似乎已从getter中复制/粘贴,而未正确修改返回类型和参数列表。
当getter返回一个值并且没有参数时,setter不返回任何值(即void
)并且接受一个参数。
而不是代码中的内容,它应该如下所示:
MethodBuilder currSetPropMthdBldr =
typeBuilder.DefineMethod("set_value", GetSetAttr, null, new [] { typeof(string) });