walruz
walruz

Reputation: 1319

How to change property for all items in list using expressions

I need to implement following function:

List<T> Set<T, TV>(
    List<T> items, Expression<Func<T, TV>> extract, Expression<Func<T, TV>> update);

So it would work like this:

List<Item> listOfModifiedItems =
    d.Set(listOfItems, i => i.SomeBooleanProperty, s => false );

As a result we would have listOfModifiedItems where all items have SomeBooleanProperty changed to false. I just don't understand how to properly do it.

Upvotes: 0

Views: 720

Answers (1)

vernou
vernou

Reputation: 7590

If anyone is looking for the answer to the original question :

public static List<T> Set<T, TV>(List<T> items, Expression<Func<T, TV>> extract, Expression<Func<T, TV>> update)
{
    // If the expression extract isn't member access
    if (extract.Body.NodeType != ExpressionType.MemberAccess)
        throw new InvalidOperationException();
    var memberAccess = (MemberExpression)extract.Body;

    // If the member access don't target a property
    if(memberAccess.Member.MemberType != System.Reflection.MemberTypes.Property)
        throw new InvalidOperationException();
    var propertyInfo = (System.Reflection.PropertyInfo)memberAccess.Member;

    // If the property don't have a setter to be updated
    if(!propertyInfo.CanWrite)
        throw new InvalidOperationException();

    var compiledUpdate = update.Compile();

    foreach (var item in items)
    {
        propertyInfo.SetValue(item, compiledUpdate.DynamicInvoke(item));
    }
    return items;
}

And this manage only the question's case. If you want manage more edge case, you will need some adaptation. Expression is very powerfull, but also complex.

Upvotes: 1

Related Questions