首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >属性选择器Expression<Func<T>>。如何获取/设置所选属性的值

属性选择器Expression<Func<T>>。如何获取/设置所选属性的值
EN

Stack Overflow用户
提问于 2011-02-22 15:55:13
回答 2查看 55.4K关注 0票数 75

我有一个对象,我想以这种方式构造它:

代码语言:javascript
复制
var foo = new FancyObject(customer, c=>c.Email); //customer has Email property

我应该如何声明第二个参数?

访问所选属性setter/getter的代码将是什么样子?

Upd。模型中有几个具有电子邮件属性的实体。因此,签名可能如下所示:

代码语言:javascript
复制
public FancyObject(Entity holder, Expression<Func<T>> selector)

和构造函数调用

代码语言:javascript
复制
var foo = new FancyObject(customer, ()=>customer.Email);
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-02-22 16:06:01

该参数将是一个Expression<Func<Customer,string>> selector。读取它可以通过平面编译:

代码语言:javascript
复制
 Func<Customer,string> func = selector.Compile();

然后你就可以访问func(customer)了。赋值是比较棘手的;对于简单的选择器,你可以希望你可以简单地分解成:

代码语言:javascript
复制
var prop = (PropertyInfo)((MemberExpression)selector.Body).Member;
prop.SetValue(customer, newValue, null);

但更复杂的表达式要么需要手动遍历树,要么需要一些4.0表达式节点类型:

代码语言:javascript
复制
        Expression<Func<Customer, string>> email
             = cust => cust.Email;

        var newValue = Expression.Parameter(email.Body.Type);
        var assign = Expression.Lambda<Action<Customer, string>>(
            Expression.Assign(email.Body, newValue),
            email.Parameters[0], newValue);

        var getter = email.Compile();
        var setter = assign.Compile();
票数 122
EN

Stack Overflow用户

发布于 2011-02-22 15:58:43

看起来该类型必须是具有两个类型参数的泛型-- source和result。例如,您可以使用:

代码语言:javascript
复制
var foo = new FancyObject<Customer, string>(customer, c => c.Email);

第一个参数的类型为TSource,第二个参数的类型为Expression<Func<TSource, TResult>>

代码语言:javascript
复制
public class FancyObject<TSource, TResult>
{
    private readonly TSource value;
    private readonly Expression<Func<TSource, TResult>> projection;

    public FancyObject(TSource value, 
                       Expression<Func<TSource, TResult>> projection)
    {
        this.value = value;
        this.projection = projection;
    }
}

通过使用非泛型类型中的静态方法,可以使这一点更简单:

代码语言:javascript
复制
var foo = FancyObject.Create(customer, c => c.Email);

可以使用类型推断来计算类型参数的。

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

https://stackoverflow.com/questions/5075484

复制
相关文章

相似问题

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