2012-10-04 24 views
4

我有這樣的事情在LinqPad力表達<>以評估局部變量

void Main() 
{ 
    var t1 = DateTimeOffset.Parse("10/1/2012"); 

    int? n1 = 1; 

    Expression<Func<Sample,bool>> x1 = ud => 
     (ud.Date == t1 && ud.Number == n1); 

    x1.ToString().Dump(); 
} 

class Sample 
{ 
    public int? Number{set;get;} 
    public DateTimeOffset Date{set;get;} 
} 

它輸出

UD =>((ud.Date ==值(UserQuery + <> C_ DisplayClass0).t1)AndAlso (ud.Number ==值(UserQuery + <>ç _DisplayClass0).n1))

是否有任何可能的方式來保持變量,但有它的輸出是這樣的:

UD =>((ud.Date ==解析( 「2012年10月1日」))AndAlso(ud.Number == 轉換(1)))

+0

你爲什麼想這樣做? – Erwin

+0

我可以檢查:您的目標是刪除捕獲類/ MemberExpression嗎? –

+0

這個想法是讓lambda輸出可讀,就是這樣。 – Kamal

回答

6

在這裏,我們走吧;輸出第一:

ud => ((ud.Date == 10/01/2012 00:00:00 +00:00) AndAlso (ud.Number == 1)) 

這不會輸出Parse(...),因爲你的表達不包含解析:您已經評價,到時候你把它變成一個lambda。

另請注意,這處理捕獲變量的一個級別。對於更復雜的(嵌套)拍攝環境中,你將不得不遞歸從捕獲類讀取值:

using System; 
using System.Linq.Expressions; 
using System.Reflection; 
using System.Runtime.CompilerServices; 
static class Program 
{ 
    static void Main() 
    { 
     var t1 = DateTimeOffset.Parse("10/1/2012"); 

     int? n1 = 1; 

     Expression<Func<Sample, bool>> x1 = ud => 
      (ud.Date == t1 && ud.Number == n1); 

     var sanitized = (Expression<Func<Sample, bool>>) 
      new Literalizer().Visit(x1); 

     Console.WriteLine(sanitized.ToString()); 
    } 
} 

class Literalizer : ExpressionVisitor 
{ 
    protected override Expression VisitMember(MemberExpression node) 
    { 
     if(node.Member.DeclaringType.IsDefined(typeof(CompilerGeneratedAttribute), false) 
      && node.Expression.NodeType == ExpressionType.Constant) 
     { 
      object target = ((ConstantExpression)node.Expression).Value, value; 
      switch (node.Member.MemberType) 
      { 
       case MemberTypes.Property: 
        value = ((PropertyInfo)node.Member).GetValue(target, null); 
        break; 
       case MemberTypes.Field: 
        value = ((FieldInfo)node.Member).GetValue(target); 
        break; 
       default: 
        value = target = null; 
        break; 
      } 
      if (target != null) return Expression.Constant(value, node.Type); 
     } 
     return base.VisitMember(node); 
    } 
} 

class Sample 
{ 
    public int? Number{set;get;} 
    public DateTimeOffset Date{set;get;} 
} 
+0

感謝您的快速回答,甚至不知道ExpressionVisitor甚至存在這樣的事情:) – Kamal

+0

它可以馬上使用。非常感謝 :) – JoanComasFdz