Question

I am trying to make a property setter delegate in il code. The current code works fine for a string but for int, bool, datetime (all value types) i get "Operation could destabilize the runtime".

 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.

I am using il code to try and avoid conversion as seen in my old code. I am trying to avoid conversion as this code needs to be as fast as possible.

Was it helpful?

Solution

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);            
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top