2

Does anyone know how to get the name of a declared variable. For instance:

Public Function returnName(variable as integer) as string

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

End Function

Ive seen it attempted a few times, most saying its impossible, explaining that IL does not store the names of variables passed, however it seems reasonable to believe there is some tangible pointer or reference that could be traced to a name. Can anyone give me some heading on this.

Why? This is purely personal research.

Ccorock
  • 892
  • 12
  • 37
  • It doesn't make a whole lot of sense (especially in your given example), where parameters to functions are assigned copies of the values used in the method call. Even in the case of `ByRef` parameters, it doesn't make a great deal more sense. There's no reason to suppose that there is a "pointer or reference" - such a thing isn't generally required. – Damien_The_Unbeliever Oct 21 '12 at 14:20
  • I think there is perfect reason to believe a pointer reference. There has to be a path to the information of that variable. ByRef, passes a reference to the variable. Can you support your position through facts? – Ccorock Oct 21 '12 at 14:29
  • 1
    Given your example method, what would you expect the answer to be when it's called by `returnName(a+5)`? Because that's a perfectly legitimate call (assuming `a` is an in scope variable at that time) – Damien_The_Unbeliever Oct 21 '12 at 16:36
  • I like the scope of your argument, however I am only interested in the scenario where a literal string (representing an integer variable) is supplied for the variable argument. Consider "Page-width" or "debt." Though a good point, your argument does not pertain to my particular needs. – Ccorock Oct 22 '12 at 15:35

2 Answers2

2

Reflection can get you the names of the method arguments, also local variables in the context of the method body, but that's where the buck stops. The only way to get them is by reading the debug information file, the .pdb that's generated for your program.

There's a good reason for that. One of the most important jobs performed by the jitter is to remove local variables from the generated machine code. And substitute them with cpu registers. It is a very important optimization that can make a great deal of difference in the speed of the code. Memory is slow, cpu registers are fast. That's an optimization that's performed in the release build of your program. Also very visible when you try to debug a release version of your program by attaching a debugger. You'll get a lot of warnings from the debugger, telling you that it doesn't know what you mean when you ask it to inspect a local variable. And also the downfall when using the .pdb file.

A backgrounder answer on the kind of optimizations performed by the jitter is available here.

Community
  • 1
  • 1
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
1

The checking method can look like this:

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

And this is how you would check variable's name, assuming it's of type Integer (your example):

Check(Of Integer)(Function() variable)

Or, with type inference, variable can be of any type:

Check(Function() variable)

Works exact for class level variables, locals get a $VB$Local_ prefix.

Same question was asked here, but in C#. I adopted code from there for VB.NET and your particular example, and tested it.

Community
  • 1
  • 1
Victor Zakharov
  • 25,801
  • 18
  • 85
  • 151
  • But, of course, there's no way (at compile time) to prevent a more complex expression being passed to this method that will cause the `DirectCast` to blow up. – Damien_The_Unbeliever Oct 21 '12 at 17:06
  • @Damien_The_Unbeliever: the interesting part is that it blows up very nicely, without throwing any exception. Your stack just goes kaboom, and the function exits prematurely. – Victor Zakharov Oct 21 '12 at 17:49