2012-10-05 19 views
7

Bir İfadenin örneğin bir ÜyeExpression'a daha fazla sarılmamış bir ParameterExpression içerip içermediğini öğrenmenin basit bir yolu var mı?Bir İfadenin "yalnız" içerip içermediğini bulma ParameterExpression

Örnek:

Basitçe benim kullanım örneğini koymak herhangi bir değerlendirme yapmadan x

x => x.Method() ? x : null < = 1 oluşumu herhangi bir değerlendirme yapmadan x

x => x.Method() ? x.Property : null < = 0 oluşumları biliyorum ki Yöntem (hiçbir paramız) ve Mülkiyet değerleri ve deponun tüm "nesne" getirmeden ifade değerlendirmek için yeterli olup olmadığını öğrenmek istiyorum.

Düzeltme: Örneğim, basitleştirilebilir. Kullanılması gereken daha fazla İfade türleri vardır (örneğin UnaryExpression).

tüm yöntem dönüş değerlerini ve özellik değerlerini biliyorsan, bir ifade verilmiş: Ben şu sorunun yanıtını arıyorum herhangi bir değerlendirme

olmadan x

x => ((Cast) x).Property < = 0 oluşumları Giriş parametresi değil, parametre değeri değil, ifadeyi değerlendirebilir miyim?

+0

kullandığınız .NET sürümü nedir? –

+0

. Net 3.5 (ama bunu kullanabileceğim bir. Net 4 sürümü de var) – lindstromhenrik

cevap

1

.NET 4 veya üzerindeyseniz, bunun için ExpressionVisitor kullanabilirsiniz.

Sana "yalnız parametreyi" define nasıl tam emin değilim ama direkt yöntem çağrıları dışında tutmak istiyorsanız, üye erişir ve dizin Böyle bir şey (denenmemiş) kullanabilir, parametrelere erişir:

böyle kullanın:

new MyExpressionVisitor().GetNumLonelyParameterExpressions(myExpression.Body) 

public class MyExpressionVisitor : ExpressionVisitor 
{ 
    private int numLonelyParameterExpressions; 

    public int GetNumLonelyParameterExpressions(Expression expression) 
    { 
     numLonelyParameterExpressions = 0; 
     Visit(expression); 
     return numLonelyParameterExpressions; 
    } 

    protected override Expression VisitParameter(ParameterExpression node) 
    { 
     // Every time we encounter a lonely parameter, increment. 
     numLonelyParameterExpressions++; 
     return base.VisitParameter(node); 
    } 

    protected override Expression VisitMethodCall(MethodCallExpression node) 
    { 
     // Don't visit parameters that have methods called on them. 
     var expr = (node.Object is ParameterExpression) 
      ? Expression.Default(node.Object.Type) 
      : node.Object; 

     // We need to make sure the arguments are visited though. 
     return base.VisitMethodCall(node.Update(expr, node.Arguments)); 
    } 


    protected override Expression VisitMember(MemberExpression node) 
    { 
      // Don't visit parameters with member accesses on them. 
      if (node.Expression is ParameterExpression) 
       return Expression.Default(node.Type); 

      return base.VisitMember(node); 
    } 

    protected override Expression VisitIndex(IndexExpression node) 
    { 
     // Same idea here. 
     var expr = (node.Object is ParameterExpression) 
      ? Expression.Default(node.Object.Type) 
      : node.Object; 

     return base.VisitIndex(node.Update(expr, node.Arguments)); 
    } 
} 
+0

Bu benim şu andaki yaklaşımım (3.5 için kendi ExpressionVisitor'um var). Ancak sayılması gereken daha fazla İfadeler var ve korkarım ki bazılarını kaçırıyorum. Bunlardan biri örneğin UnaryExpression: x => ((Cast) x) .Property. – lindstromhenrik

+0

@lindstromhenrik: Sanırım “yalnız” olarak tanımlamak zorunda kalacaksınız, sanki bunu içeriyormuşsunuz gibi, oldukça belirsiz. – Ani

+0

Daha iyi bir açıklama yapmayı denedim ama yine de sorun ne diyeceğime gerçekten emin değilim ;-) – lindstromhenrik

İlgili konular