2013-10-23 129 views
1

前言如何將lambda運算符的右側轉換爲字符串?

我知道這是可能使用反射和表達式的組合搶一個變量的名稱。然而,在財產/現場鏈接的情況下,是否可以獲取更多的變量名?

示例功能

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"

+0

迭代想你的意思'expression.Body作爲MemberExpression' :-P –

+1

所有這一切信息就在那裏,如果你願意的話。 'MemberExpression'的'Expression'將是另一個具有'person'的表達式。 – Servy

+0

@Servy是的,事實證明它就在那裏。感謝您的正確方向! – James

回答

2

它看起來像最簡單的方法是對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)); 
} 
+1

這隻適用於表達式只不過是一系列成員訪問的表示;如果它是其他東西,那麼它將無法工作。它也忽略了最內在的表達。在這兩種情況下,它是閉包對象,但如果你的表達式*不是閉包,那麼它不太可能按照預期工作。例如,如果最裏面的表達式是一個靜態變量或一個常量,那麼它將不會顯示。 – Servy

0

如果你只是想打印出來的lambda作爲一個字符串的整個身體也很簡單:

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

這將輸出' 「值(MyNamespace.Program + <> c__DisplayClass1).person.Name」' – James

+1

@詹姆斯這在技術上是什麼表達式包含;該類型是閉包的表示。 – Servy