如何从lambda表达式中获取值?

时间:2017-02-22 08:05:24

标签: c# .net lambda expression-trees

我有这堂课:

osgi.jdbc.driver.class=org.postgresql.Driver
url=jdbc:postgresql://localhost:5432/test
dataSourceName=test
user=test
password=test
protocolVersion=3

它的用法如下:

    ConnectionPool pool = new ConnectionPool();
    pool.setUrl("jdbc:postgresql://localhost:5432/test");
    pool.setUser("test");
    pool.setPassword("test");
    pool.setProtocolVersion(3);
    Connection conn = pool.getConnection();

在搜索类中,如何在不使用public class CustomerFilter { public int Id { get; set; } public int Name { get; set; } } 的情况下获取属性的值?类似的东西:

public class Search
{
    private Expression<Func<CustomerFilter, bool>> customerfilter;

    public Expression<Func<CustomerFilter, bool>> CustomerFilter
    {
        set { customerfilter = value; }
    }
}

var search = new Search();
search.CustomerFilter = (x => x.Id == 1);

3 个答案:

答案 0 :(得分:2)

不要理解你为什么需要它。但是,你可以这样做:

public class Search
{
    private Expression<Func<CustomerFilter, bool>> customerfilter;

    public Expression<Func<CustomerFilter, bool>> CustomerFilter
    {
        set { customerfilter = value; }
    }

    public object GetValue(CustomerFilter filter)
    {
        var property = (customerfilter.Body as BinaryExpression).Left;
        var lambda =Expression.Lambda(property, customerfilter.Parameters.First());
        return lambda.Compile().DynamicInvoke(filter);
    }
}

有了这样的用法:

var search = new Search();
search.CustomerFilter = (x => x.Id == 1);
var filter = new CustomerFilter {Id = 12};
search.GetValue(filter).Dump();

我将12作为输出

答案 1 :(得分:0)

有一个类和一个属性CustomerFilter代表非常不同的东西,这有点误导。据我了解,该类最好命名为Customer

public class Customer
{
    public int Id { get; set; }
    public int Name { get; set; }
}

public class Search
{
    private Expression<Func<Customer, bool>> customerfilter;

    public Expression<Func<Customer, bool>> CustomerFilter
    {
        set { customerfilter = value; }
    }
}

var search = new Search();
search.CustomerFilter = (x => x.Id == 1);

然后更明显的是customerFilter.Id课程中没有属性Search。您只有一个表达式,可以使用任何(!)Customer并将其转换为bool。它是通过将Customer.Id与给定值进行比较来实现的,但Search并不知道这一点。

如果您需要在Search中获取比较ID,我建议您将CustomerFilter属性的类型更改为具有公共ComparisonId属性的类并生成过滤器表达式基于那个id:

class CustomerIdFilter // note: this will not replace your existing CustomerFilter which I have renamed to Customer
{
    public CustomerIdFilter(int id){ ComparisonId = id; }
    public int ComparisonId{ get; private set}
    // To filter use this
    public bool IsValid(Customer c){ return c.Id == ComparisonId; }
    // or maybe something similar to this, if necessary
    public Expression<Func<Customer, bool>>FilterExpression
    {
        get
        {
            return (x=>x.Id == ComparisonId);
        }
    } 
}

您的代码将更改为s.th.像这样:

public class Search
{
    private CustomerIdFilter customerfilter;

    public CustomerIdFilter CustomerFilter
    {
        set { customerfilter = value; }
    }
}

var search = new Search();
search.CustomerFilter = new CustomerIdFilter(1);

答案 2 :(得分:0)

根据xwlantian的回答更进一步,我做了以下内容,它适用于简单的表达式:

var value = Expression.Lambda(((BinaryExpression)customerFilter.Body).Right).Compile().DynamicInvoke();