Lambda表达式中的赋值

时间:2019-03-06 23:47:46

标签: c#

我想定义一些lambda表达式来表示类实例属性的更新。

我尝试这样写:

Expression<Action<User>> update = user => user.Name = "Joe Foo";

但是我有一个编译错误:

  

错误CS0832   表达式树可能不包含赋值运算符。

如何使用lambda表示此更新。

编辑

我的目标是使业务服务将更新发送到通用存储库。该存储库可以分析lambda的表达式以构建查询以发送到数据库引擎。

业务服务的示例可以是:

public void DoStuff(String userId, ...)
{
  // Business logic here
  // ...

  // Persist updates determined above
  this.repository.Update(
    // First parameter is the filter of entities to updates
    x => x.Id == userId,
    // Next parameters are updates to apply
    x => x.FirstName = "John",
    x => x.LastName = "Foo",
    ...);
}

3 个答案:

答案 0 :(得分:5)

  

我想定义一些lambda表达式来表示类实例属性的更新。

您不能总是得到想要的东西。

我们设计了表达式树lambda来表示非变异操作,因此在表达式树中使用=+=++等lambda是非法的。

  

如何用lambda表示此更新?

委托lambda不受此限制;你可以说

Action<User> update = user => user.Name = "Joe Foo";

您能否说说为什么需要这个?可能会有更好的方法来实现您的目标。 您可能会问一个XY问题。这是一个问题,您有一个问题,您有一个不好的解决方案,现在您要问的是有关不好的解决方案的问题,而不是问题。您要解决的问题是什么?

答案 1 :(得分:1)

正如其他人所说,C#不允许在表达式树中使用赋值表达式。

另一种方法是使用new表达式。这样就可以用一个lambda表示更新:

repository.Update(
    x => x.Id == userId, // Where clause
    x => new User{ // Update expression
        Modified = DateTime.Now,
        ModifiedBy = "John",
        Amount = x.Amount + 10
    }
);

其中x代表更新表达式中实体的旧状态。

void Update(Expression<Func<T, bool>> filter, Expression<Func<T, T>> update)

如果您不需要引用旧值,则可以使用此简化签名(根据您的评论):

void Update(Expression<Func<T, bool>> filter, Expression<Func<T>> update)

答案 2 :(得分:0)

很难猜出您想如何使用表达式。 如果您想深入思考问题,也许此片段会有所帮助:

var user = new User();

var paramExpr = Expression.Parameter(typeof(User), "user");
var propertyExpression = Expression.Property(paramExpr, "Name");
Expression.Lambda<Action<User>>(
    Expression.Assign(
        propertyExpression,
        Expression.Constant("Joe Foo")
    ),
    new List<ParameterExpression>() { paramExpr }
).Compile()(user);

Console.WriteLine(user.Name); //Joe Foo

在那里,您:

1)定义ParameterExpression-您的输入;

2)设置如何获取您感兴趣的类的属性(.Name

3)最后,定义表达式(并对其进行调用),以执行测试用户变量