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 MemberExpressions 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
LambdaExpressionwhoseBodyis aPropertyExpressionthat has aMemberfield with aNameof "Item2" and anExpressionthat is aFieldExpressionfor getting the value oftuple. Note thatPropertyExpressionandFieldExpressionare internal types that inherit fromMemberExpression.So you need to get the
(Body as MemberExpression).Member.Nameinstead 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.