I doing next thing... I pass into some function the field of some controls, like:
class ScenarioSelector
{
public ScenarioSelector()
{
SubjectInfo.SetStr(lbl_labs_header.Text);
}
}
class SubjectInfo
{
public static void SetStr(object obj)
{
string name = obj.GetType().Name;
string full_name = obj.GetType().FullName;
Type t = obj.GetType();
//FieldInfo fi = FieldInfo.GetFieldFromHandle(/*I don't have any handle here*/);
//Somehow understand that passed object is... "ScenarioSelector.lbl_labs_header.Text" and set it's value depending from it.
}
}
Function SetStr should understand the field name of passed object and set it's value depending of it's name.
I tried something, but can't get what I need, I only getting System.String as name.
Whole idea behind that is interface translation. I want to store in file something like: [ScenarioSelector.lbl_labs_header.Text][TEXT_ON_THIS_LABEL] And easy set it by calling function SetStr
Maybe you have some ideas of how to make it another way or fix my way?
P.S. Based on Medinoc example I did this:
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 (previousMember == null) //this is first one
{
switch (memberBody.Member.MemberType)
{
case MemberTypes.Field:
((FieldInfo)memberBody.Member).SetValue(/*How to get the object instance?*/, "some_val");
break;
case MemberTypes.Property:
break;
default:
break;
}
}
if (memberBody.Expression.NodeType == ExpressionType.Constant && previousMember != null) //If it's the 'last' member, replace with type
memberName = previousMember.DeclaringType.Name;
memberNames.Add(memberName);
previousMember = memberBody.Member;
body = memberBody.Expression;
}
memberNames.Reverse();
Console.WriteLine("Member: {0}", string.Join(".", memberNames));
}
But still don't know how to get instance of object to set needed value.
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.