C# 如何使用反射获取变量名?

C# 如何使用反射获取变量名?,c#,reflection,C#,Reflection,比如说, static void Main() { var someVar = 3; Console.Write(GetVariableName(someVar)); } 该程序的输出应为: someVar 我如何使用反射来实现这一点?使用反射是不行的GetVariableName传递的是数字3,而不是变量。您可以通过IL的代码检查来实现这一点,但这可能太难了。使用反射不可能做到这一点,因为一旦编译到IL,变量就不会有名称。但是,可以使用表达式树并将变量升级为闭包: sta

比如说,

static void Main()
{
    var someVar = 3;

    Console.Write(GetVariableName(someVar));
}
该程序的输出应为:

someVar

我如何使用反射来实现这一点?

使用反射是不行的
GetVariableName
传递的是数字3,而不是变量。您可以通过IL的代码检查来实现这一点,但这可能太难了。

使用反射不可能做到这一点,因为一旦编译到IL,变量就不会有名称。但是,可以使用表达式树并将变量升级为闭包:

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

    return body.Member.Name;
}
请注意,这相当慢,所以不要在应用程序的性能关键路径中使用它。每次运行这段代码时,都会创建几个对象(这会造成GC压力),并在后台调用许多不可内联的方法,并使用一些重反射

有关更完整的示例,请参阅

更新

使用C#6.0,语言中添加了
nameof
关键字,这允许我们执行以下操作:

static void Main()
{
    var someVar = 3;

    Console.Write(nameof(someVar));
}

这显然更方便,并且与将字符串定义为常量字符串文字的成本相同。

@helen我的问题非常简单,而不是他提出的分散的问题,我仍然认为这很不一样。这背后的原因可能是什么?我不确定它的性能是否真的很差。可能会导致性能问题的是编译表达式树,但您在这里没有这样做。请在使用Reflector编译
GetVariableName(()=>someVar)
的地方查找您自己。每次运行这段代码时,都会创建几个对象,并在幕后调用许多不可内联的方法,并使用一些重反射。使用表达式树不是免费的。是的,你是对的。它确实有性能成本。但与编译表达式树相比,它“相对”小。我明白你的意思。您正在谈论在运行时通过调用表达式树的
.Compile()
方法来编译表达式树。我同意这会更贵。+1表示“更贵”:
static void Main()
{
    var someVar = 3;

    Console.Write(nameof(someVar));
}