首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将Expression<Func<TClass、TField>>转换为Expression<Func<TClass、object>>

将Expression<Func<TClass、TField>>转换为Expression<Func<TClass、object>>
EN

Stack Overflow用户
提问于 2018-07-01 11:19:07
回答 1查看 85关注 0票数 2

我正在尝试创建一个通用的"update表达式生成器“--一个可以传递的对象,用于指示哪些字段需要分配什么值。我所做的是:

代码语言:javascript
复制
public class UpdateExpression<TClass> : Dictionary<Expression<Func<TClass, object>>, object> 
{};

public class  UpdateExpressionBuilder<TClass>
{
    private UpdateExpression<TClass> fieldsValues;

    public UpdateExpressionBuilder()
    {
        fieldsValues = new UpdateExpression<TClass>();
    }

    public UpdateExpressionBuilder<TClass> Add<TField>(Expression<Func<TClass, TField>> field, TField value) 
    {
        fieldsValues.Add(field, value);
        return this;
    }

    public UpdateExpression<TClass> Build()
    {
        return fieldsValues;
    }
}

这意味着用作:

代码语言:javascript
复制
var personUpdateExpression = new UpdateExpressionBuilder<Person>()
            .Add(p => p.FirstName, "David")
            .Add(p => p.MiddleName, "A")
            .Build();

然后,我可以将personUpdateExpression作为参数发送到任何方法,例如数据库更新。

问题是调用fieldsValues.Add(field, value)不编译。错误是:

代码语言:javascript
复制
error CS1503: Argument 1: cannot convert from
'System.Linq.Expressions.Expression<System.Func<TClass, TField>>' to
'System.Linq.Expressions.Expression<System.Func<TClass, object>>'

我尝试添加约束where TField : class, new(),但这并没有改变任何事情。

当更改Add到Add(Expression<Func<TClass, object>> field, object value)的签名时,它工作得非常完美。但是,我放松了编译时类型检查,以便Add(p => p.FirstName, 123)能够编译,但在运行时失败。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-01 12:26:34

我完全同意黛西在评论中写的话.你还是想要些什么:

代码语言:javascript
复制
public UpdateExpressionBuilder<TClass> Add<TField>(Expression<Func<TClass, TField>> field, TField value)
{
    var body = field.Body;

    // Boxing for value types
    if (typeof(TField).IsValueType)
    {
        body = Expression.Convert(body, typeof(object));
    }

    Expression<Func<TClass, object>> field2 = Expression.Lambda<Func<TClass, object>>(body, field.Parameters);

    fieldsValues.Add(field2, value);
    return this;
}

然后

代码语言:javascript
复制
var personUpdateExpression = new UpdateExpressionBuilder<Person>()
    .Add(p => p.FirstName, "David")
    .Add(p => p.MiddleName, "A")
    .Add(p => p.Age, 30)
    .Build();

请注意,您的示例仅限于字符串,但我为int添加了一个示例。

最后我们重写了Expression。对于引用类型,只需更改Func<>的返回类型即可。对于值类型,需要显式装箱。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51122797

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档