I am trying to write code that can set arbitrary fields on caller-provided objects which may include anonymous ones. Creating delegates is not possible (Expression compiler realizes that anonymous objects' fields are readonly), so I chose to emit some IL. However, when doing this I am running into VerificationException ("Operation could destabilize he runtime"). The same simple code runs just fine on objects with regular fields. Fails on readonly fields. What else could be done here? I am running .Net 4.6.2.
Thanks in advance!
class TestRegular
{
private string field;
}
class TestReadOnly
{
private readonly string field;
}
class Program
{
static void Main(string[] args)
{
Verify(new TestRegular()); // this works
Verify(new TestReadOnly()); // this does not work
Verify(new { field = "abc" }); // this does not work
Console.WriteLine("Done");
}
private static void Verify<T>(T test)
{
var fields = typeof(T).GetFields(BindingFlags.Instance | BindingFlags.NonPublic);
Action <T, object> setter = CompileSetter<T>(fields[0]);
setter(test, "value");
}
private static Action<TResult, object> CompileSetter<TResult>(FieldInfo field)
{
string methodName = field.ReflectedType.FullName + ".TestSetter";
DynamicMethod setterMethod = new DynamicMethod(methodName, null, new[] { typeof(TResult), typeof(object) }, true);
ILGenerator gen = setterMethod.GetILGenerator();
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldarg_1);
gen.Emit(OpCodes.Castclass, field.FieldType);
gen.Emit(OpCodes.Stfld, field);
gen.Emit(OpCodes.Ret);
return (Action<TResult, object>)setterMethod.CreateDelegate(typeof(Action<TResult, object>));
}
}
Aucun commentaire:
Enregistrer un commentaire