How to get variable name using reflection?
It is not possible to do this with reflection, because variables won't have a name once compiled to IL. However, you can use expression trees and promote the variable to a closure:
static string GetVariableName<T>(Expression<Func<T>> expr)
{
var body = (MemberExpression)expr.Body;
return body.Member.Name;
}
You can use this method as follows:
static void Main()
{
var someVar = 3;
Console.Write(GetVariableName(() => someVar));
}
Note that this is pretty slow, so don't use it in performance critical paths of your application. Every time this code runs, several objects are created (which causes GC pressure) and under the cover many non-inlinable methods are called and some heavy reflection is used.
For a more complete example, see here.
UPDATE
With C# 6.0, the nameof
keyword is added to the language, which allows us to do the following:
static void Main()
{
var someVar = 3;
Console.Write(nameof(someVar));
}
This is obviously much more convenient and has the same cost has defining the string as constant string literal.
Java Reflection: How to get the name of a variable?
As of Java 8, some local variable name information is available through reflection. See the "Update" section below.
Complete information is often stored in class files. One compile-time optimization is to remove it, saving space (and providing some obsfuscation). However, when it is is present, each method has a local variable table attribute that lists the type and name of local variables, and the range of instructions where they are in scope.
Perhaps a byte-code engineering library like ASM would allow you to inspect this information at runtime. The only reasonable place I can think of for needing this information is in a development tool, and so byte-code engineering is likely to be useful for other purposes too.
Update: Limited support for this was added to Java 8. Parameter (a special class of local variable) names are now available via reflection. Among other purposes, this can help to replace @ParameterName
annotations used by dependency injection containers.
Get variable name. javascript reflection
Since you're using .NET as an example, let's delve briefly into that. In C#, you could create a function that takes an Expression
:
void BadArgument<T>(Expression<Func<T>> argExpr)
{
}
But in order to be able to extract the variable name from a call to this function, you would have to make sure the call always uses exactly the right syntax (even though there is no way to enforce this at compile time):
if(x < 0)
BadArgument(() => x);
So it can be done, but it's very fragile and pretty slow. You're basically generating instructions to create a whole expression tree based on the lambda expression () => x
, just so the function you call can parse out that expression tree and try to find the name of the argument.
Can this sort of thing be done in javascript? Sure!
In javascript, closures are produced via internal functions, so the equivalent of the above lambda expression would be:
function(){return x;}
And since javascript is a scripting language, each function is the equivalent of its own definition as a string. In other words, calling .toString()
on the above function will yield:
function(){return x;}
This jsfiddle shows how you can leverage this in a logging-style function. You are then free to parse the resulting function string, which will be only slightly more trouble than parsing the .NET Expression Tree would be. Furthermore, getting the actual value of x
is even easier than in .NET: you just call the function!
But just because you can do it doesn't mean you should. It's nice as a gee-whiz parlor trick, but when it comes right down to it, it's not worth it:
- It's fragile: what if some developer doesn't use it right and gives you a function that you can't parse?
- It doesn't work with minification: imagine getting a message that variable
a
had an incorrect value because your minified function changed your variable names. - It adds overhead: even a minifier can't shorten
function(){return x;}
to be smaller than"x"
. - Finally, it's complicated. 'nuff said.
Getting a variable by name using reflection in Java
You get a field
field = getClass().getDeclaredField(name);
on whatever whatever type this
is, presumably com.whatever.project.Hexagon
. But then you try to retrieve the field on an object of type com.badlogic.gdx.graphics.Color
.
System.out.println(field.get(c));
This is wrong. The javadoc states
Returns the value of the field represented by this
Field
, on the
specified object.
Color
does not have a Color
field.
What you want is probably
field.get(this)
How to get variable name? - java
You can get all field name by reflection
Class yourClass = YourClass.class
Field[] fields = yourClass.getFields();
for(Field f: fields){
f.getName();
}
or if you want mapping then go for Map
Map<String, String> propertyToValueMap
if you are trying to read method's local variable name, then it is not that simple to fetch also a signal that you are doing something wrong
Why is it not possible to get local variable names using Reflection?
You have to differentiate between the human-readable text-based form of CLI and the machine-readable compiled form of CLI.
In text CLI, local variables indeed can have names (see §II.15.4.1.3 of ECMA-335, as explained in Damien's answer).
But in the binary form, local variables don't have names. For that, look at §II.23.2.6, where the binary format for a method's local variable signature (list of all its local variables) is specified. And it doesn't contain any mention of variable names:
So, if some tool wants to know the original name of a local variable, it has to look into the debugging information contained in the PDB file. If that's not present, there is no way to find out the name.
JavaScript Reflection: obtaining a variable's name?
1. You could try parsing the script's text.
JSFiddle Example
var x = function(){}
var myUnknownNamedVar1 = myUnknownNamedVar2 = x;
var txt = (document.currentScript && document.currentScript.textContent) ||
(document.scripts && document.scripts[1]
&& document.scripts[1].textContent);
var arr = txt.match(/var\s*(.*)\s*=\s*x\b/);
arr[1] = arr[1].replace(/\s+$/,"");
var vars = arr[1].split(/\s*=\s*/);
// vars: ["myUnknownNamedVar1", "myUnknownNamedVar2"]
2. You can try comparing values
JSFiddle Example
var x = function(){}
var myUnknownNamedVar1 = myUnknownNamedVar2 = x;
var vars = [];
for (var prop in window){
if (window[prop] == x)
vars.push(prop);
}
// vars: ["x", "myUnknownNamedVar1", "myUnknownNamedVar2"]
Note: Both methods will need refining (eg recursion, better/more match patterns). The second one only looks at global variables, whereas some variables in closures may not be exposed to the global namespace. Also, there are objects of objects.
Related Topics
Creating a Zip Archive in Memory Using System.Io.Compression
No Overflow Exception for Int in C#
Validateantiforgerytoken Purpose, Explanation and Example
Access to Modified Closure (2)
How to Programmatically Fill in a Form and 'Post' a Web Page
Why Some Types Do Not Have Literal Modifiers
Httpclient - a Task Was Cancelled
Usercontrol' Constructor with Parameters in C#
Regular Expression to Split on Spaces Unless in Quotes
How to Pass Values Across the Pages in ASP.NET Without Using Session
Is It Safe to Check Floating Point Values for Equality to 0