简体   繁体   English

我正在尝试从属性设置器创建一个委托

[英]I am trying to make a to create a delegate from property setter

I am trying to make a property setter delegate in il code. 我试图在il代码中创建一个属性设置器委托。 The current code works fine for a string but for int, bool, datetime (all value types) i get "Operation could destabilize the runtime". 当前代码对于字符串可以正常工作,但对于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();

I have used unbox and box to try and get int working this two lines can also be a castclass and string will work but still get same error with value types. 我已经使用了unbox和box来尝试使int工作,这两行也可以是castclass和string可以工作,但对于值类型仍然会出现相同的错误。

I am using il code to try and avoid conversion as seen in my old code. 我正在使用il代码来尝试避免转换,如我的旧代码所示。 I am trying to avoid conversion as this code needs to be as fast as possible. 我试图避免转换,因为此代码需要尽可能快。

You know the type of the property so you can just generate the appropriate code. 您知道属性的类型,因此只需生成适当的代码即可。 If it is a reference type then you have to cast, if its a value type then you have to unbox. 如果是引用类型,则必须强制转换;如果是值类型,则必须取消装箱。 This worked well: 这很好用:

    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.

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