[mise à jour pour plus de clarté]
D'abord; cast le Expression
d'un MemberExpression
.
Un MemberExpression
a deux choses intéressantes:
- .Membre de l'
PropertyInfo
/ FieldInfo
pour le membre
- .L'Expression - l'expression à évaluer pour obtenir le "obj" pour le .Membre
c'est à dire si vous pouvez évaluer l' .Expression
de "obj", et l' .Member
est FieldInfo
, alors vous pouvez obtenir la valeur réelle via .GetValue(obj)
sur le FieldInfo
(et PropertyInfo
est très similaire).
Le problème est que l'évaluation de l' .Expression
est très délicat ;-p
Évidemment, vous avez de la chance si elle s'avère être un ConstantExpression
- , mais dans la plupart des cas, il n'est pas, ça pourrait être une ParameterExpression
(dans ce cas, vous aurez besoin de connaître la valeur du paramètre que vous souhaitez évaluer), ou toute autre combinaison de Expression
s.
Dans de nombreux cas, un simple (peut-être paresseux) option est l'utilisation d' .Compile()
pour obtenir le .NET framework pour faire le gros du travail; vous pouvez ensuite évaluer le lambda comme tapé délégué (passage de tous les paramètres que le lambda oblige). Ce n'est pas toujours une option, cependant.
Pour montrer la complexité de ce qui est; considérez cet exemple trivial (où j'ai codé en dur à chaque étape, plutôt que de tester etc):
using System;
using System.Linq.Expressions;
using System.Reflection;
class Foo
{
public string Bar { get; set; }
}
static class Program
{
static void Main()
{
Foo foo = new Foo {Bar = "abc"};
Expression<Func<string>> func = () => foo.Bar;
MemberExpression outerMember = (MemberExpression)func.Body;
PropertyInfo outerProp = (PropertyInfo) outerMember.Member;
MemberExpression innerMember = (MemberExpression)outerMember.Expression;
FieldInfo innerField = (FieldInfo)innerMember.Member;
ConstantExpression ce = (ConstantExpression) innerMember.Expression;
object innerObj = ce.Value;
object outerObj = innerField.GetValue(innerObj);
string value = (string) outerProp.GetValue(outerObj, null);
}
}