使用 Func 在对象上设置 属性
Set property on object using Func
为了 mock/testing 的目的,我想要一个方法,我可以传入某种类型的对象集合,一个 Func 到 select 属性 来更新,以及我想将每个 属性 设置为的值。我想在不使用反射的情况下执行此操作。我也可以使它成为一个扩展方法并将其包装起来以进行模拟,但那是在解决此问题之后。
下面是一个为 List<Foo>
中的每个更新 属性 Bar
的示例:
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; });
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!");
为了 mock/testing 的目的,我想要一个方法,我可以传入某种类型的对象集合,一个 Func 到 select 属性 来更新,以及我想将每个 属性 设置为的值。我想在不使用反射的情况下执行此操作。我也可以使它成为一个扩展方法并将其包装起来以进行模拟,但那是在解决此问题之后。
下面是一个为 List<Foo>
中的每个更新 属性 Bar
的示例:
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; });
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!");