C#lambda体到字符串

时间:2012-08-15 16:52:49

标签: c# reflection lambda

我有以下lambda表达式

    var expr = a => (a.Name == "Alex" && a.DateCreated < DateTime.Now.AddHours(2))

我想在字符串中获取带有运行时值的表达式主体,如果我调用expr.Body.ToString(),我会得到以下字符串作为回报。

    {((a.Name == "Alex") AndAlso (a.DateCreated < DateTime.Now.AddHours(2)))}

所以只是为了澄清我希望获得DateTime.Now.AddHours(2)的值。过去几天我一直在疯狂地搜索网页而没有任何结果。这可能取决于我不知道要搜索什么。希望你们能够提供帮助:)

2 个答案:

答案 0 :(得分:2)

您需要将DateTime调用移出lambda:

DateTime endDate = DateTime.Now.AddHours(2);
Expression<Func<YourClass, bool>> expr = a => (a.Name == "Alex" && a.DateCreated < endDate);

即使这样,你也会在表达式中显示闭包,而不是值。

要将特定日期作为打印值,您需要一个常量,即:

Expression<Func<YourClass, bool>> expr = a => (a.Name == "Alex" && a.DateCreated < DateTime.Parse("10/2/2012"));

这将显示DateTime.Parse调用,但至少仍会显示该值(因为它是表达式中的常量。)

构建表达式时,DateTime属性和方法(NowAddHours)将成为表达式本身的一部分。闭环变量也会发生这种情况。表达式必须包括构建完整lambda所需的所有语句,包括DateTime.Now.AddHours(2)

这是设计 - 如果您将其转换为实体框架查询(例如AddHours is one of the Canonical Functions),则需要在服务器上解析DateTime.Now.AddHours()。如果用常量换出它,它将不会按预期运行。

答案 1 :(得分:0)

以下代码有效,但我不确定您是否想要使用它。

Expression<Func<A,bool>> expr = a => (a.Name == "Alex" && a.DateCreated < DateTime.Now.AddHours(2));

var expr1 = expr.Body as BinaryExpression;
var expr2 = expr1.Right as BinaryExpression; //a.DateCreated < DateTime.Now.AddHours(2)
var expr3 = expr2.Right as MethodCallExpression; //DateTime.Now.AddHours(2)

var obj = expr3.Object as MemberExpression; //DateTime.Now
var pi = obj.Member as PropertyInfo;
var dt = pi.GetValue(null); //Call DateTime.Now


var arg = expr3.Arguments[0] as ConstantExpression;
var result = expr3.Method.Invoke(dt, new object[] { arg.Value }); //Call AddHours

-

public class A
{
    public string Name { set; get; }
    public DateTime DateCreated { set; get; }
}