使用Func在对象上设置属性

时间:2018-10-11 23:16:21

标签: c# linq generics func

出于模拟/测试目的,我想要一种方法,可以传递某种类型的对象的集合,可以使用Func选择要更新的属性,还可以设置要设置每个属性的值至。我想这样做而不使用反射。我还可以使其成为扩展方法并包装以进行模拟,但这是在解决此问题之后。

下面是一个为Bar中的每个属性更新属性List<Foo>的示例:

public class Foo 
{
    public string Bar { get; set; }
}

// I want something like this
public List<Foo> UpdateProp_Ideal<TProperty>(List<Foo> foos, Func<Foo, TProperty> propertyFunc, TProperty valueToSet)
{
    return foos.Select(x => { propertyFunc(x)[Somehow get setter?] = valueToSet; return x; }).ToList();
}

// I could do this, but it has a broader scope (and more typing)
public List<Foo> UpdateProp(List<Foo> foos, Func<Foo, Foo> updateFunc)
{
    return foos.Select(updateFunc).ToList();
}

// Ideal call
var updatedFoos = UpdateProp_Ideal(listOfFoos, x => x.Bar, "Updated!");

// Working call
var updatedFoos = UpdateProp(listOfFoos, x => { x.Bar = "Updated!"; return x; });

1 个答案:

答案 0 :(得分:2)

public static List<T> UpdateProp_Ideal<T, TProperty>(
    this List<T> foos, Expression<Func<T, TProperty>> propertyFunc, TProperty valueToSet)
{
    var body = Expression.MakeBinary(
        ExpressionType.Assign, propertyFunc.Body, Expression.Constant(valueToSet)
    );
    var action = Expression.Lambda<Action<T>>(body, propertyFunc.Parameters).Compile();
    foos.ForEach(action);
    return foos;
}

用法:

var updatedFoos = UpdateProp_Ideal(listOfFoos, x => x.Bar, "Updated!");