I'm creating a simple way to get the Name
and Value
of Expressions in C#. However, I found a case I cannot figure out. See the code below:
public void GetValue_Object_TIn_Property_Test()
{
string val = "value";
var tuple = Tuple.Create(new object(), val);
Expression<Func<object, string>> expression = x => tuple.Item2;
Assert.AreEqual(val, expression.GetValue());
}
The .GetValue()
method is my extension method.
Basically this expression-tree consists of a LambdaExpression
, two MemberExpression
s and a ConstantExpression
, in that order.
When I try to get the name of tuple.Item2
I get memberExpression.Member.Name
from the last MemberExpression
. This gives me "tuple" instead of "Item2". How can I get "Item2" instead?
Also, when I try to get the value of the expression, I get the entire tuple instead of Item2
. I'm using the following method to get the value:
public override bool TryGetValue(
MemberExpression memberExpression,
out T value
) {
value = default(T);
bool success = false;
var fieldInfo = memberExpression.Member as FieldInfo;
if (success = (fieldInfo != null))
{
var valueObj = fieldInfo.GetValue(expression.Value);
if (success = (valueObj is T || valueObj == null))
{
value = (T)valueObj;
}
}
return success;
}
Where the MemberExpression
again is the last MemberExpression
. What am I doing wrong here? What is the exact case I am missing?
Thank you in advance
Actually, the tree is a
LambdaExpression
whoseBody
is aPropertyExpression
that has aMember
field with aName
of "Item2" and anExpression
that is aFieldExpression
for getting the value oftuple
. Note thatPropertyExpression
andFieldExpression
are internal types that inherit fromMemberExpression
.So you need to get the
(Body as MemberExpression).Member.Name
instead of theBody.Expression.Member.Name
.Think of the tree as
MemberExpression
(getMember
:Item2 fromExpression
:MemberExpression
(getMember
:tuple fromExpression
:[surrounding class])).Have you used LINQPad? It's
Dump()
command can show you this and more.