Without prior experience of lambda expressions, I managed to construct an example:
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
namespace TestsA
{
class TestLambdaExpression
{
class Inner { public int tata; }
string toto;
Inner tutu;
static void Test3<T>(Expression<Func<T>> exp)
{
Expression body = exp.Body;
List<string> memberNames = new List<string>();
while(body.NodeType == ExpressionType.MemberAccess)
{
MemberExpression memberBody = (MemberExpression)body;
memberNames.Add(memberBody.Member.Name);
body = memberBody.Expression;
}
memberNames.Reverse();
Console.WriteLine("Member: {0}", string.Join(".", memberNames));
}
public static void Test()
{
TestLambdaExpression obj = new TestLambdaExpression();
obj.toto = "Hello world!";
obj.tutu = new Inner();
obj.tutu.tata = 42;
Test3(() => obj.toto);
Test3(() => obj.tutu.tata);
}
}
}
Calling TestLambdaExpression.Test
should output:
Member: obj.toto
Member: obj.tutu.tata
Edit:
For your special output, a test can be added:
static void Test3<T>(Expression<Func<T>> exp)
{
Expression body = exp.Body;
List<string> memberNames = new List<string>();
MemberInfo previousMember = null;
while(body.NodeType == ExpressionType.MemberAccess)
{
MemberExpression memberBody = (MemberExpression)body;
string memberName = memberBody.Member.Name;
//If it's the 'last' member, replace with type
if(memberBody.Expression.NodeType == ExpressionType.Constant && previousMember != null)
memberName = previousMember.DeclaringType.name;
memberNames.Add(memberName);
previousMember = memberBody.Member;
body = memberBody.Expression;
}
memberNames.Reverse();
Console.WriteLine("Member: {0}", string.Join(".", memberNames));
}
Edit2: For modifying the variable, I managed to make this:
private static void TestAssign<T>(Expression<Func<T>> exp, T toAssign)
{
Expression assExp = Expression.Assign(exp.Body, Expression.Constant(toAssign));
Expression<Func<T>> newExp = exp.Update(assExp, null);
newExp.Compile().Invoke();
}
It's probably not the fastest nor the most efficient way to do it, but it should be the most versatile.