[英]I am trying to make a to create a delegate from property setter
我试图在il代码中创建一个属性设置器委托。 当前代码对于字符串可以正常工作,但对于int,bool,datetime(所有值类型),我会得到“操作可能会使运行时不稳定”。
DynamicMethod method = new DynamicMethod( "Setter", typeof ( void ), new[]
{
typeof ( T ), typeof ( Object )
}, true );
var ilgen = method.GetILGenerator();
ilgen.Emit( OpCodes.Ldarg,0 );
ilgen.Emit( OpCodes.Castclass, property.DeclaringType );
ilgen.Emit( OpCodes.Ldarg,1 );
ilgen.Emit(OpCodes.Unbox_Any, property.PropertyType);
ilgen.Emit( OpCodes.Box,property.PropertyType );
ilgen.Emit( OpCodes.Call, property.GetSetMethod() );
ilgen.Emit( OpCodes.Ret );
var action = method.CreateDelegate( typeof ( Action<T, Object> ) ) as Action<T, Object>;
return action;
//var target = Expression.Parameter(typeof(T), "obj");
//var value = Expression.Parameter(typeof(Object), "value");
//var body = Expression.Assign(
// Expression.Property(Expression.Convert(target, property.DeclaringType), property),
// Expression.Convert(value, property.PropertyType));
//var lambda = Expression.Lambda<Action<T, Object>>(body, target, value);
//return lambda.Compile();
我已经使用了unbox和box来尝试使int工作,这两行也可以是castclass和string可以工作,但对于值类型仍然会出现相同的错误。
我正在使用il代码来尝试避免转换,如我的旧代码所示。 我试图避免转换,因为此代码需要尽可能快。
您知道属性的类型,因此只需生成适当的代码即可。 如果是引用类型,则必须强制转换;如果是值类型,则必须取消装箱。 这很好用:
ilgen.Emit(OpCodes.Ldarg, 1);
if (property.PropertyType.IsValueType)
ilgen.Emit(OpCodes.Unbox_Any, property.PropertyType);
else ilgen.Emit(OpCodes.Castclass, property.PropertyType);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.