如何使用Func <>更新对象属性?

时间:2018-08-11 20:10:34

标签: c# lambda func

  

通过某种方式可以更新对象属性吗   Func带有lambda表达式?


Foo类

public class Foo
{
    public int Id      { get; set; }
    public string Name { get; set; }
    public int Age     { get; set; }
    //... many others
}

实用程序类

public static class Updater
{
    public Foo FooUpdate(Foo item, params Func<Foo, object> properties)
    {
        foreach(var property in properties)
        {
            //take value of property and set it on item object
        }
        return item
    } 
}

初始通话

   var updatedFoo = Updater.FooUpdate(item, p => p.Id = 10, p => p.Name = "Test", ...);

FooUpdate方法之后,我想接收updatedFoo对象,该对象在给定的调用中具有给定的值参数。 Id = 10Name = "Test"

3 个答案:

答案 0 :(得分:4)

Func<Foo, object>签名无效。 Lambda p => p.Id = 10不返回object。 如果您只想更改现有方法即可使用,则可以这样做:

 public Foo FooUpdate(Foo item, params Action<Foo> properties)
 {
     foreach(var property in properties)
     {
        property(item);
     }
     return item
 } 

但是请注意,这是一个非常糟糕的设计。首先,您的方法都会修改传递的item并返回它-它应该对其进行修改(并返回void)或保留item不变,克隆它,然后进行修改并返回克隆。第二,我发现此Util方法根本没有价值。对其的任何调用都等同于仅逐行应用更新。

var updatedFoo = Updater.FooUpdate(item, p => p.Id = 10, p => p.Name = "Test", ...);

相同
item.Id = 10;
item.Name = "Test";
/* ... */

答案 1 :(得分:2)

您无需在此处使用Func,因为您无需返回任何内容。您可以使用Action来修改foo:

public Foo FooUpdate(Foo item, params Action<Foo>[] propertySetters)
{
       foreach(var propertySetter in propertySetters)
       {
            propertySetter(item);
       }

       return item;
}

答案 2 :(得分:0)

我写了一个小方法,允许通过选择一个属性来更新对象的值。

用法:var result = UpdateByField(company, 1, x => x.Id);

private T UpdateByField<T, TValue>(T obj, TValue value, Expression<Func<T, TValue>> selector)
{
    var memberExpression = selector.Body as MemberExpression;

    var field = memberExpression.Member as FieldInfo;
    var property = memberExpression.Member as PropertyInfo;

    if (field != default)
        field.SetValue(obj, value);

    if (property != default)
        property.SetValue(obj, value);

    return obj;
}