Sto scherzando con gli alberi delle espressioni, ma sono un po 'bloccato.
Ho questa espressione:
Expression<Func<IX, int>> expr = i => i.GetAll(1, b, method());
Dove :
int b = 2;
public static int method()
{
return 3;
}
public interface IX
{
int GetAll(int a, int b, int c);
}
Ora voglio ottenere il nome del metodo e dei valori dei parametri per questo metodo. Il nome del metodo è semplice, ma i valori dei parametri sono una parte più difficile. So che posso analizzarli da solo, ma avrei bisogno di gestire tutti i casi ( ConstantExpression
, MemberExpression
, MethodCallExpression
e forse più di cui non sono a conoscenza). Quindi stavo pensando se ci fosse un modo "generale" per ottenere i loro valori. ad es. 1, 2, 3.
È possibile ottenere gli argomenti di MethodCallExpression
in questione e creare Func<object>
compilato da loro (tipi di valore di boxe se necessario), che possono quindi essere valutati.
Per esempio:
var args = from arg in ((MethodCallExpression)expr.Body).Arguments
let argAsObj = Expression.Convert(arg, typeof(object))
select Expression.Lambda<Func<object>>(argAsObj, null)
.Compile()();
Questo ovviamente esploderà se il corpo dell'espressione non è un'espressione di chiamata al metodo o se uno qualsiasi degli argomenti del metodo non può essere valutato come tale (ad esempio se dipendono dall'argomento dell'espressione).
Ovviamente, puoi fare un lavoro migliore se conosci i tipi di argomenti del metodo in anticipo. Per il tuo esempio specifico, questo dovrebbe funzionare:
var args = from arg in ((MethodCallExpression)expr.Body).Arguments
select Expression.Lambda<Func<int>>(arg, null)
.Compile()();
Non puoi semplicemente ottenere tutti i parametri e poi compilarli ed eseguirli? Non vedo come sarebbe possibile ottenere tutti i valori senza eseguire se possono essere chiamate di metodo.