简体   繁体   中英

Emit property to set a dictionary value

I try to emit a set field method for a property in a dynamic assembly.

The C# code wanted is :

private readonly Dictionary<string, object> propertyBag = new Dictionary<string, object>();

public string PropertyName
{
    set { propertyBag["PropertyName"] = value; }
}

PropertyName and its type must be dynamic

My code to emit the setter is:

PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyName, PropertyAttributes.None, propertyType, Type.EmptyTypes);
FieldBuilder fieldBuilder = typeBuilder.DefineField("propertyBag", typeof(Dictionary<string, object>), FieldAttributes.Private);

MethodBuilder setMethodBuilder = typeBuilder.DefineMethod($"set_{propertyName}", MethodAttributes.Public | MethodAttributes.HideBySig, null, new[] { propertyType });
ILGenerator setIL = setMethodBuilder.GetILGenerator();
setIL.Emit(OpCodes.Ldarg_0);
setIL.Emit(OpCodes.Ldarg_1);
setIL.Emit(OpCodes.Ldfld, fieldBuilder);
setIL.Emit(OpCodes.Ldstr, propertyName);
setIL.Emit(OpCodes.Callvirt, fieldBuilder.FieldType.GetMethod("set_Item", new Type[] { typeof(string), typeof(object) }));
setIL.Emit(OpCodes.Ret);

propertyBuilder.SetSetMethod(setMethodBuilder);

When running the code which set the property, i have an

AccessViolationException : Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

An idea?

The parameter order of set_item seems to be off.

Have a look at this decompiled example, value (arg1) should be the second parameter, not the first:

IL_0000: ldarg.0
IL_0001: ldfld class [System.Private.CoreLib]System.Collections.Generic.Dictionary`2<string, object> C::propertyBag
IL_0006: ldstr "PropertyName"
IL_000b: ldarg.1
IL_000c: callvirt instance void class [System.Private.CoreLib]System.Collections.Generic.Dictionary`2<string, object>::set_Item(!0, !1)
IL_0011: ret

Taken from here: sharplab.io

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM