2010-04-02 86 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来做到这一点,但这可能是太困难了。