Reputation: 2827
I am trying to generate a class dinamicaly through a List of dictionaries with the following code:
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;
}
I get this error when trying to set the value of the property.:
An unhandled exception of type 'System.Reflection.TargetParameterCountException' occurred in mscorlib.dll Additional information: Parameter count mismatch.
I checked and I have in my sample 3 properties and I will assign 3 values.
The code is taken and Little bit adapted from here
Any idea?
Upvotes: 0
Views: 215
Reputation: 70701
You have defined the setter method incorrectly. You seem to have copy/pasted from the getter, without correctly modifying the return type and argument list.
While the getter returns a value and has no arguments, a setter returns no value (i.e. is void
) and takes one argument.
Instead of what you have in your code, it should look like this:
MethodBuilder currSetPropMthdBldr =
typeBuilder.DefineMethod("set_value", GetSetAttr, null, new [] { typeof(string) });
Upvotes: 1