2010-04-02 67 views
34

例如,如何使用反射獲取變量名稱?

static void Main() 
{ 
    var someVar = 3; 

    Console.Write(GetVariableName(someVar)); 
} 

這個程序的輸出應該是:

someVar 

我怎樣才能做到這一點使用反射?

+1

@helen我的問題很簡單,與他提出的問題的分散性相反,我仍然認爲這個問題有點不同。 – 2010-04-02 10:38:39

+0

這可能是什麼原因呢? – Dested 2010-04-02 13:11:54

回答

57

這是不可能的反射,因爲一旦編譯爲IL,變量將不會有一個名稱。但是,您可以使用表達式樹,促進變量封閉:

static string GetVariableName<T>(Expression<Func<T>> expr) 
{ 
    var body = (MemberExpression)expr.Body; 

    return body.Member.Name; 
} 

如下您可以使用此方法:

static void Main() 
{ 
    var someVar = 3; 

    Console.Write(GetVariableName(() => someVar)); 
} 

請注意,這是相當緩慢的,所以不要用它在您的應用程序的性能關鍵路徑中。每次運行該代碼時,都會創建幾個對象(這會導致GC壓力),並且在封面下會調用許多不可插入的方法,並使用一些沉重的反射。

有關更完整的示例,請參見here

UPDATE

在C#6.0中,nameof關鍵字添加到語言,這使我們能夠做到以下幾點:

static void Main() 
{ 
    var someVar = 3; 

    Console.Write(nameof(someVar)); 
} 

這顯然是更方便,並且具有相同的成本已經將字符串定義爲常量字符串文字。

+0

我不確定它在性能方面真的很差。可能導致性能問題的原因是編譯表達式樹,但這裏不做。 – 2010-04-02 19:06:46

+0

尋找你的自我GetVariableName(()=> someVar)'使用Reflector編譯爲。每次運行代碼時,都會創建幾個對象,並在封面下調用許多不可乾的方法,並使用一些沉重的反射。使用表達式樹不是免費的。 – Steven 2010-04-02 20:48:27

+0

是的,你是對的。它確實具有性能成本。但與編譯表達式樹相比,它「相對」小。 – 2010-04-02 23:09:32

0

你不能使用反射。 GetVariableName傳遞數字3,而不是一個變量。你可以通過代碼檢查IL來做到這一點,但這可能是太困難了。