2012-10-21 112 views
2

有谁知道如何获取声明变量的名称。例如:查找变量的声明名称

Public Function returnName(variable as integer) as string 

Dim [string] as string = string.empty 
[string] = variable.name 
return [string] 

End Function 

我见过它尝试了几次,最称其不可能的,并解释说IL没有存储通过变量的名字,但它似乎有理由相信有一些有形的指针或引用,可以被追溯到一个名字。任何人都可以给我一些标题。

为什么?这完全是个人研究。

+0

它并没有形成很多意义(特别是在你给出的例子中),其中函数的参数被分配了方法调用中使用的值的副本。即使在'ByRef'参数的情况下,它也没有多大意义。没有理由假设有一个“指针或引用” - 通常不需要这样的事情。 –

+0

我认为有完美的理由相信一个指针参考。必须有一条通往该变量信息的路径。 ByRef将一个引用传递给变量。你能通过事实来支持你的立场吗? – Ccorock

+1

考虑到你的示例方法,当returnName(a + 5)'调用它时,你期望得到的答案是什么?因为这是一个完全合法的调用(假设'a'在当时是一个范围变量) –

回答

2

反射可以得到方法参数的名称,也可以是方法体的上下文中的局部变量,但这就是降压停止的地方。获取它们的唯一方法是读取调试信息文件,即为您的程序生成的.pdb。

有一个很好的理由。由抖动执行的最重要的工作之一是从生成的机器代码中删除局部变量。并用cpu寄存器替换它们。这是一个非常重要的优化,可以使代码的速度发生很大的变化。内存很慢,cpu寄存器很快。这是在您的程序的发布版本中执行的优化。当您尝试通过附加调试程序来调试程序的发行版本时也很明显。你会从调试器中得到很多警告,告诉你当你要求它检查一个局部变量时,它不知道你的意思。同时也是使用.pdb文件时的失败。

关于由抖动执行的优化类型的背景知识答案是available here

1

的检查方法可以是这样的:

Private Shared Function Check(Of T)(expr As Expression(Of Func(Of T))) As String 
    Dim body = DirectCast(expr.Body, MemberExpression) 
    Return body.Member.Name 
End Function 

这是你将如何检查variable的名字,假设它是Integer类型(您的例子):

Check(Of Integer)(Function() variable) 

或者,与类型推断,variable可以是任何类型:

Check(Function() variable) 

准确地为类级别变量工作,当地人获得$VB$Local_前缀。

同样的问题被问到here,但在C#中。我从那里采用了VB.NET的代码和您的特定示例,并对其进行了测试。

+0

但是,当然,没有办法(在编译时)阻止将更复杂的表达式传递给此方法,这将导致“DirectCast”崩溃。 –

+0

@Damien_The_Unbeliever:有趣的部分是,它吹得很好,没有抛出任何异常。你的栈只会去kaboom,并且该函数过早退出。 – Neolisk

+0

非常有趣。 – Ccorock