2012-10-05 14 views
7

Czy istnieje prosty sposób sprawdzenia, czy wyrażenie zawiera parametr expression, który nie jest dalej zawijany, na przykład element członkowski expressionExpression.Sprawdzanie, czy wyrażenie zawiera "samotny" parametr Wyrażenie

Przykład:

x => x.Method() ? x : null < = 1 wystąpienie x bez dalszej oceny

x => x.Method() ? x.Property : null < = 0 wystąpień x bez dalszej oceny

Wystarczy umieścić mój przypadek użycia jest to, że wiem, że Metoda (bez parametrów) i wartości właściwości i chcesz dowiedzieć się, czy to wystarczy, aby ocenić wyrażenie bez pobierania całego "obiektu" ze sklepu.

Edytuj: Mój przykład może być uproszczony. Istnieje więcej typów ekspresji, które muszą być obsługiwane (na przykład UnaryExpression).

x => ((Cast) x).Property < = 0 wystąpień x bez dalszej oceny

szukam odpowiedzi na następujące pytanie:

danym wyrazem, jeśli wiem, że wszystkie wartości powrotu metody i wartości majątkowych parametr wejściowy, ale nie sama wartość parametru, czy mogę ocenić wyrażenie?

+0

Jaka wersja .NET używasz? –

+0

To .net 3.5 (ale ja też mam wersję .net 4, gdzie mógłbym użyć tego) – lindstromhenrik

Odpowiedz

1

Jeśli korzystasz z .NET 4 lub nowszego, możesz użyć do tego celu ExpressionVisitor.

Nie jestem pewien, w jaki sposób można zdefiniować „samotny parametr”, ale jeśli chcesz wykluczyć bezpośrednie wywołań metod, członek dostęp i indeksowania dostęp parametrów, można użyć mniej więcej tak (niesprawdzone):

Używaj go tak:

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

To jest moje obecne podejście (mam własnego ExpressionVisitor dla 3.5). Jednak jest więcej Wyrażeń, które trzeba policzyć i obawiam się, że tęsknię za niektórymi. Jednym z nich jest na przykład UnaryExpression: x => ((Cast) x) .Property. – lindstromhenrik

+0

@lindstromhenrik: Myślę, że będziesz musiał zdefiniować "samotny" naprawdę dobrze, jeśli to załączysz, to jest dość niejasne. – Ani

+0

Próbowałem dać lepsze wyjaśnienie, ale nadal nie jestem do końca pewien, jak nazwać ten problem ;-) – lindstromhenrik

Powiązane problemy