2010-09-28 18 views
8

dal momento che possiamo:Reverse of Expression <Func <T,TResult>> .Compile()?

Expression<Func<int, bool>> predicate = x => x > 5; 
var result = Enumerable.Range(0,10).Where(predicate.Compile()); 

Come posso:

Func<int,bool> predicate = x => x > 5; 
Expression<Func<int,bool>> exp = predicate.Decompile(); 

Cioè, voglio ottenere il corrispondente Expression del Func. È possibile?

+1

No, non è possibile. Nessuna costruzione di espressioni viene emessa nel compilatore. Nessuna alchimia qui. – leppie

+0

possibile duplicato di [conversione di un Func .net a un'espressione .net >] (http://stackoverflow.com/questions/767733/converting-a-net-funct-to-a-net-expressionfunct) – nawfal

risposta

7

Non c'è magia Decompile() per un delegato, a corto di decostruire l'IL (forse con mono.cecile). Se vuoi un albero di espressioni, devi avviare con un albero di espressioni, quindi avere Expression<Func<int, bool>> nell'intervallo.

Come un caso limite, è possibile ottenere informazioni di base sulla delegato metodo dal delegato .Method (la MethodInfo) e .Target (la arg0) - tuttavia, per la maggior parte degli scenari che coinvolgono un lambda o metodo anonimo questo punterà al compilatore -generare il metodo sulla classe di acquisizione, quindi non ti aiuterà molto. E 'praticamente limitato a scenari come:

Func<string,int> parse = int.Parse; 
5

Passa il lambda a un metodo che accetta uno Expression<> e il compilatore C# ti passerà un albero di espressioni in fase di esecuzione. Tuttavia questo funziona solo se si passa direttamente lambda, non se si tenta di passare un'istanza delegata creata da un lambda.

var exp = Decompile(x => x > 5); 

public Expression<Func<int, bool>> Decompile(Expression<Func<int, bool>> exp) 
{ 
    return exp; 
} 

L'opzione più vicina che ho trovato per decompilazione un'istanza delegato è dettagliata in this post sul blog di Jean-Baptiste Evain che lavora nel team Mono. Usa l'eccellente progetto Mono.Cecil per decompilare l'IL in un AST personalizzato, quindi lo mappa nel miglior modo possibile nelle espressioni LINQ.

+1

No Se si passa 'x => x> 5' a' Decompile', passerà un 'Expression'. Voglio decompilare un 'Func ', senza sapere che è contenuto. –

+0

Come ha detto Marc, non è possibile. Ho solo pensato di pubblicare un esempio del più vicino che potresti ottenere per la decompilazione. –

+1

Sì, sapevo che stavi postando un esempio del più vicino quando ho visto la tua risposta. Ma qualcun altro non la pensa così, e vota in basso :( –

1

È possibile non decompilare il delegato, ma si può certamente creare un nuovo albero di espressione che semplicemente chiamate il delegato:

Func<int, bool> predicate = x => x > 5; 
Expression<Func<int, bool>> exp = x => predicate(x); 
3

Puoi provare a utilizzare la mia biblioteca:
https://github.com/ashmind/expressive

Anche se potrebbe non funzionare come è per i risultati di Compile(), dal momento che è un DynamicMethod e ottenere l'IL non è semplice. Se si implementa la propria implementazione IManagedMethod per DynamicMethod, tuttavia, dovrebbe funzionare.

Ho intenzione di implementare gli adattatori DynamicMethod, ma non so ancora quando.

+0

Grande. Ci proverò. Grazie mille. –

Problemi correlati