2009-08-14 8 views
5

Desidero utilizzare l'espressione Linq per alcune funzioni dinamiche. Ho bisogno di E, O e Non espressioni .. Non ho potuto ottenere molto ..Espressione C# che utilizza E e Nessuna espressione insieme in base a AST

Vogliamo verificare se alcune funzionalità sono state abilitate o meno nel nostro sistema e in base a questo decideremo se mostrare la voce di menu o no. abbiamo formato le regole in formato XML, so di convertire la regola in AST ma non so mappare all'espressione di Linq.

regole sono come: Feature1Enabled E Feature2Eenabled o (Feature3Disabled E non Feature5Enabled)

Qui "Feature1Enabled", "Feature2Eenabled" ecc sono il nome della funzione. Passeremo questa stringa alla funzione IsFeatureEnabled per verificare se una funzionalità è stata abilitata o meno.

public delegate bool IsEnabledDelegate(string name, string value); 

    public static bool IsFeatureEnabled(string name, string value) 
    { 
     if (name == "MV") 
      return true; 

     if (name == "GAS" && value == "G") 
      return true; 
     //More conditions goes here 
     return false; 
    } 

    static void Main(string[] args) 
    { 
     Expression<Func<string, string, bool>> featureEnabledExpTree = 
         (name, value) => IsFeatureEnabled(name, value); 

     //I want the equal of the following statement in C# Linq Expression 

     bool result = IsFeatureEnabled("MV", "") && IsFeatureEnabled("GAS", "G") || !IsFEatureEnabled("GAS", "F") 

    } 

Voglio l'equivalente al risultato bool = IsFeatureEnabled ("MV", "") & & IsFeatureEnabled ("GAS", "G") || ! IsFEatureEnabled ("GAS", "F")

in LINQ espressione formato .. Comunque io possa convertire in modo dinamico in base alle mie notazioni AST ..

Grazie mille .. Se avete bisogno di più informazioni , dimmi nei commenti ..

+0

(ad esempio rivisto per mostrare edificio featureEnabledExpTree in fase di esecuzione sulla base dei dati) –

risposta

4
ParameterExpression name = Expression.Parameter(typeof(string), "name"), 
     value = Expression.Parameter(typeof(string), "value"); 

    // build in reverse 
    Expression body = Expression.Constant(false); 
    body = Expression.Condition(
     Expression.AndAlso(
      Expression.Equal(name, Expression.Constant("GAS")), 
      Expression.Equal(value, Expression.Constant("G")) 
     ), Expression.Constant(true), body); 
    body = Expression.Condition(
     Expression.Equal(name, Expression.Constant("MV")), 
     Expression.Constant(true), body); 

    Expression<Func<string, string, bool>> featureEnabledExpTree = 
     Expression.Lambda<Func<string, string, bool>>(body, name, value); 


    // test in isolation 
    var featureEnabledFunc = featureEnabledExpTree.Compile(); 
    bool isMatch1 = featureEnabledFunc("MV", "") 
     && featureEnabledFunc("GAS", "G") || !featureEnabledFunc("GAS", "F"); 

E poi, se è necessario il secondo porzione come un albero di espressione troppo:

//I want the equal of the following statement in C# Linq Expression 
    Expression<Func<bool>> test = 
     Expression.Lambda<Func<bool>>(
      Expression.OrElse(
       Expression.AndAlso(
        Expression.Invoke(featureEnabledExpTree, 
         Expression.Constant("MV"), 
         Expression.Constant("") 
        ), 
        Expression.Invoke(featureEnabledExpTree, 
         Expression.Constant("GAS"), 
         Expression.Constant("G") 
        ) 
       ), 
       Expression.Not(
        Expression.Invoke(featureEnabledExpTree, 
         Expression.Constant("GAS"), 
         Expression.Constant("F") 
        ) 
       ) 
      ) 
     ); 

    bool isMatch = test.Compile()(); 
+0

Ciao Marc, grazie mille. Sì, ho bisogno di costruire l'espressione in fase di runtime .. Se possibile, per favore dammi qualche dettaglio in più .. –

+0

Non ho bisogno di avere se la dichiarazione .. o altra parte da valutare. Ho bisogno solo dell'espressione –

+0

Non ci sono istruzioni if. OrElse/AndAlso sono solo i normali C# && e || operatori (con la loro strategia di valutazione in cortocircuito indicata dai nomi nell'albero delle espressioni). –

1

così?

Expression<Func<bool>> featureEnabledExpTree =() => 
    IsFeatureEnabled("MV", "") && 
    IsFeatureEnabled("GAS", "G") || 
    !IsFEatureEnabled("GAS", "F"); 
+0

"Tuttavia posso convertirli dinamicamente in base alle mie notazioni AST" - che sto interpretando nel senso che deve essere costruito in base ai dati, quindi la capacità del compilatore di tradurre C# per esprimere alberi potrebbe non essere utile. –

Problemi correlati