我正在尝试编写可以在调用者提供的对象上设置任意字段的代码,这些对象可能包括匿名对象。创建委托是不可能的(表达式编译器意识到匿名对象的字段是只读的),所以我选择发出一些 IL。但是,这样做时,我遇到了 VerificationException(“操作可能会破坏运行时”)。相同的简单代码在具有常规字段的对象上运行得很好。在只读字段上失败。这里还能做什么?我正在运行.Net 4.6.2。
提前致谢!
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>));
}
}