【问题标题】:How do I convert the right of a lambda operator to a string?如何将 lambda 运算符的右侧转换为字符串?
【发布时间】:2013-10-23 01:13:56
【问题描述】:

前言

我知道可以使用反射和表达式的组合来获取变量的名称。但是,在属性/字段链接的情况下,是否可以不仅仅获取变量的名称?

示例函数

public void DisplayVarName<T>(Expression<Func<T>> expression){
    MemberExpression memberExpression = 
        expression.Body as MemberExpression;        
    Console.WriteLine(memberExpression.Member.Name);
}

示例 1

string helloWorldStr = "Hello World";
DisplayVarName(() => helloWorldStr); // Outputs "helloWorldStr"

示例 2

Person person = new Person(){ Name = "Santa Clause" };
DisplayVarName(() => person.Name); // Outputs "Name"

问题

有没有办法将 lambda 运算符右侧的内容存储在字符串中?

示例 2 将生成 "person.Name" 而不仅仅是 "Name"

【问题讨论】:

  • 认为你的意思是expression.Body as MemberExpression :-P
  • 所有信息都在里面,如果你愿意的话。 MemberExpressionExpression 将是另一个包含 person 的表达式。
  • @Servy 是的,原来一切都在那里。感谢您朝着正确的方向前进!

标签: c# reflection lambda expression


【解决方案1】:

看起来最简单的方法是迭代MemberExpression.Expression

public static void DisplayVarName<T>(Expression<Func<T>> expression)
{
    List<string> memberNames = new List<string>();
    MemberExpression memberExpression = 
        expression.Body as MemberExpression;

    do
    {
        memberNames.Add(memberExpression.Member.Name);
        memberExpression = 
            memberExpression.Expression as MemberExpression;                
    } while (memberExpression != null);

    memberNames.Reverse();
    Console.WriteLine(String.Join(".", memberNames));
}

【讨论】:

  • 这仅在表达式只是一系列成员访问的表示时才有效;如果是其他任何东西,那么它将无法正常工作。它也忽略了最里面的表达式。在这两种情况下,它是闭包对象,但如果您的表达式 isn't 是闭包,那么它不太可能按预期工作。例如,如果最里面的表达式是静态变量或常量,则不会显示。
【解决方案2】:

如果您只想将 lambda 的整个主体打印为字符串,这非常简单:

public void DisplayVarName<T>(Expression<Func<T>> expression){     
    Console.WriteLine(expression.Body);
}

【讨论】:

  • 这将输出"value(MyNamespace.Program+&lt;&gt;c__DisplayClass1).person.Name"
  • @James 从技术上讲,该表达式包含的内容;该类型是闭包的表示。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-24
  • 2011-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多