C # 4.0: alberi espressione vs. CodeDom

Quali sono le differenze tra alberi di espressione e CodeDom? Quale dovrei usare per quale scenario?

Gli alberi di espressione hanno molto in comune con (per esempio) un AST . Non è mappato direttamente al codice, ma è molto suscettibile alla costruzione dagli algoritmi. Ad esempio, se stai analizzando una formula:

((a + 2) / b) 

questo è:

 ParameterExpression a = ..., b = ... var body = Expression.Divide( Expression.Add(a, Expression.Constant(2)), b); var lambda = Expression.Lambda(body,a,b); // optionally with generics 

In effetti, ho fatto esattamente questo, usando un parser che costruisce un albero degli oggetti, con oggetti che generano l’espressione completa tramite un’implementazione “visitatore”. In .NET 4.0, il più ricco supporto per le espressioni consente di supportare la maggior parte degli scenari e di compilarlo su richiesta.

Un altro uso chiave delle espressioni è che puoi decostruirle in fase di runtime, quindi nel tuo codice potresti avere:

 Foo(x => x.SomeMethod(1, "abc")); 

ed estrai il metodo SomeMethod : informazioni, 1 e "abc" ecc.


mappe di codice per codificare . Si tratta di istruzioni ecc., Molto simili a come si scrive codice normale. L’uso più comune della codifica è per la generazione del codice, come parte degli strumenti. Puoi usarlo per la compilazione dynamic, ma per essere onesti è più difficile. Non sono un fan La caratteristica interessante è che un albero della libertà potrebbe funzionare per più lingue.


Un altro concorrente qui dovrebbe essere DynamicMethod e / o ILGenerator . Questo non si associa ad un AST (espressione) e non può essere utilizzato per generare codice sorgente (codedom), ma consente l’accesso completo agli strumenti MSIL. Naturalmente, richiede anche che tu pensi in termini di stack ecc., Ma è molto efficiente ed efficace per la meta-programmazione.


Se ILGenerator è troppo rigido e la codifica è un PITA, allora un’altra opzione è la generazione di codice in fase di esecuzione come stringa . Quindi passare attraverso CSharpCodeProvider per compilarlo. Esistono parti del runtime di base che eseguono questa operazione ( XmlSerializer IIRC).


Quindi per riassumere:

  • meta-programmazione: ILGenerator o CSharpCodeProvider ; anche Expression in 4.0 (ma questo è abbastanza limitato in 3.5)
  • gestione AST: Expression
  • analisi al runtime: Expression
  • generazione del codice in più lingue: codice-dom

Gli alberi di espressione vengono utilizzati per creare espressioni. Creazione di codice sorgente in fase di runtime. CodeDom è usato per compilare il codice sorgente. Deve esistere prima di poterlo build. Gli alberi delle espressioni sono più flessibili, ma molto più difficili da usare.

Se si desidera aggiungere script alla propria applicazione, utilizzare CodeDom. Se vuoi fare riflessioni molto avanzate e simili, usa gli alberi di espressione, ma io non lo consiglio.