📜 ⬆️ ⬇️

Setting an object property using lambda expressions

If there is a need for the same processing of assigning a value to a property of an object, then lambda expressions can be used. Such a task may arise when validating or processing values, assignment logging, etc.

The simplest method that does not take into account the assignment of the properties of nested objects is as follows:

public static class ObjectHelper { public static void Set<T, TProp>(this T obj, Expression<Func<T, TProp>> property, TProp value) { if (obj == null) throw new ArgumentNullException("obj"); if (property == null) throw new ArgumentNullException("property"); var memberExpression = (MemberExpression) property.Body; var targetPropertyInfo = (PropertyInfo) memberExpression.Member; //     obj  value    targetPropertyInfo.SetValue(obj, value); } } 

This only works to assign the property of the object itself, but not the property of the nested object. I.e:

  myObject.Set(x => x.MyProperty, "bla-bla-bla"); //  myObject.Set(x => x.MyProperty.InnerProperty, "bla-bla-bla"); //   

It does not work, because the assignment in this case does not go to the object in myObject.MyProperty, but to the object myObject.
(And if the types of MyProperty and myObject are the same, an exception will not be thrown, and the program will have a hidden error!)
')
In order to work for the properties of nested objects, you need to walk through the expression tree and get the desired object, the property of which will be assigned a value:

  public static class ObjectHelper { public static void Set<T, TProp>(this T obj, Expression<Func<T, TProp>> property, TProp value) { if (obj == null) throw new ArgumentNullException("obj"); if (property == null) throw new ArgumentNullException("property"); object target = obj; var memberExpression = (MemberExpression) property.Body; var targetPropertyInfo = (PropertyInfo) memberExpression.Member; if (memberExpression.Expression.NodeType != ExpressionType.Parameter) { var expressions = new Stack<MemberExpression>(); while (memberExpression.Expression.NodeType != ExpressionType.Parameter) { memberExpression = (MemberExpression)memberExpression.Expression; expressions.Push(memberExpression); } while (expressions.Count > 0) { var expression = expressions.Pop(); var propertyInfo = (PropertyInfo)expression.Member; target = propertyInfo.GetValue(target); if (target == null) throw new NullReferenceException(expression.ToString()); } } //     obj, target  value    targetPropertyInfo.SetValue(target, value); } } 

  myObject.Set(x => x.MyProperty, "bla-bla-bla"); //  myObject.Set(x => x.MyProperty.InnerProperty, "bla-bla-bla"); //  

Source: https://habr.com/ru/post/259567/


All Articles