0

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?

5
  • 1
    why don't you use ExpandoObject Class ? Commented Dec 5, 2014 at 13:29
  • I didn't heard about it. Could you please explain it? Thanks Commented Dec 5, 2014 at 13:30
  • 2
    @blacai ExpandoObject is best explained by MSDN Commented Dec 5, 2014 at 13:56
  • And about the error I am getting? Commented Dec 5, 2014 at 14:05
  • check this stackoverflow.com/questions/1653046/… Commented Dec 5, 2014 at 15:35

1 Answer 1

1

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) });
Sign up to request clarification or add additional context in comments.

1 Comment

I should check better when typing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.