2013-11-25 3 views
1

Я пытаюсь создать делегат setterter в il-коде. Текущий код отлично работает для строки, но для int, bool, datetime (все типы значений) я получаю «Операция может дестабилизировать время выполнения».Я пытаюсь создать делегат из свойства setter

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(); 

Я использовал распаковывать и коробку, чтобы попытаться получить Int работают эти две линии также могут быть castclass и строка будет работать, но все еще получаю ту же ошибку с типами значений.

Я использую код il, чтобы избежать конверсии, как показано в моем старом коде. Я пытаюсь избежать преобразования, поскольку этот код должен быть как можно быстрее.

ответ

1

Вы знаете тип собственности, чтобы вы могли просто сгенерировать соответствующий код. Если это ссылочный тип, то вам нужно отбрасывать, если его тип значения, то вам нужно распаковать. Это хорошо работает:

ilgen.Emit(OpCodes.Ldarg, 1); 
    if (property.PropertyType.IsValueType) 
     ilgen.Emit(OpCodes.Unbox_Any, property.PropertyType); 
    else ilgen.Emit(OpCodes.Castclass, property.PropertyType);    
Смежные вопросы