How to assign properties in general using the Expression.Assign selector with the target object type?

I am trying to use an expression selector to assign properties from one type of object to another, where properties are of different types. This is the code that I still have:

var type1 = new Type1(); var type2 = new Type2(); ... var propMap = new List<Tuple<Expression<Func<Type1, object>>, Expression<Func<TradeStaticAttributesItemModel, object>>>> { new Tuple<Expression<Func<Type1, object>>, Expression<Func<Type2, object>>>(x => x.Prop1, x => x.Prop1), new Tuple<Expression<Func<Type1, object>>, Expression<Func<Type2, object>>>(x => x.Prop2, x => x.Prop2) }; foreach (var prop in propMap) { if (prop.Item1.Compile()(type1) != prop.Item2.Compile()(type2)) { ParameterExpression valueParameterExpression = Expression.Parameter(prop.Item2.Body.Type); var assign = Expression.Lambda<Action<Type1, object>>(Expression.Assign(prop.Item1.Body, valueParameterExpression), prop.Item1.Parameters.Single(), valueParameterExpression); Action<Type1, object> setter = assign.Compile(); setter(type1, prop.Item2.Compile()(type2)); } } 

However, I am, however, getting the error "ParameterExpression of type" System.String "cannot be used for the delegation parameter of type" System.Object "when the property type is string . I assume this will happen for any other type except object . Any idea how to make this code work for such a situation?

I found a potential answer here using Expression.Convert, but I can't get it to work.

+2
c # expression
Oct 10
source share
1 answer

OK, I got this working with the following code:

 var type1 = new Type1(); var type2 = new Type2(); ... var propMap = new List<Tuple<Expression<Func<Type1, object>>, Expression<Func<TradeStaticAttributesItemModel, object>>>> { new Tuple<Expression<Func<Type1, object>>, Expression<Func<Type2, object>>>(x => x.Prop1, x => x.Prop1), new Tuple<Expression<Func<Type1, object>>, Expression<Func<Type2, object>>>(x => x.Prop2, x => x.Prop2) }; foreach (var prop in propMap) { if (prop.Item1.Compile()(type1) != prop.Item2.Compile()(type2)) { ParameterExpression valueParameterExpression = Expression.Parameter(typeof(object)); // This handles nullable types Expression targetExpression = prop.Item1.Body is UnaryExpression ? ((UnaryExpression)prop.Item1.Body).Operand : prop.Item1.Body; var assign = Expression.Lambda<Action<Type1, object>>( Expression.Assign(targetExpression, Expression.Convert(valueParameterExpression, targetExpression.Type)), prop.Item1.Parameters.Single(), valueParameterExpression); Action<Type1, object> setter = assign.Compile(); setter(type1, prop.Item2.Compile()(type2)); } } 

This works for types with a null value (as commented out). Now I know Expression, but if anyone has improvements for this code, please feel free to suggest them!

+4
Oct 10
source share



All Articles