get name of variable as string?

  • Thread starter Thread starter Zytan
  • Start date Start date
Z

Zytan

Shot in the dark, since I know C# doesn't have macros, and thus can't
have a stringizer operator, but I know that you can get the name of
enums as strings, so maybe you can do the same with an ordinary
variable (like an int) somehow. Is it possible? int.ToString()
returns the value of the int as a string, not the name, so I am
thinking 'no'.

Zytan
 
Zytan said:
Shot in the dark, since I know C# doesn't have macros, and thus can't
have a stringizer operator, but I know that you can get the name of
enums as strings, so maybe you can do the same with an ordinary
variable (like an int) somehow. Is it possible? int.ToString()
returns the value of the int as a string, not the name, so I am
thinking 'no'.

What are you attempting to do that you need this behavior?
 
What you want to do is called Reflection. Google "C# Reflection". Also take
a look at the System.Reflection namespace.
 
Bill Butler said:
What are you attempting to do that you need this behavior?

There seem to be several postings a week here ostensibly about reflection,
when ordinary non-meta-level techniques are perfectly suitable.
It may not be the case here, but I blame Perl for all this name vs. named
confusion... (Always good to have something to blame :))
 
Zytan said:
Shot in the dark, since I know C# doesn't have macros, and thus can't
have a stringizer operator, but I know that you can get the name of
enums as strings, so maybe you can do the same with an ordinary
variable (like an int) somehow. Is it possible? int.ToString()
returns the value of the int as a string, not the name, so I am
thinking 'no'.

To my best knowledge C# does not have anything
similar to macro and stringifier operator.

What you can get for enums is the string representation
of the value not of the variable name.

Arne
 
This isn't correct. There is a one-to-many relationship between a class
and the variables that can have a reference to it. That being said, you
can't figure out all the references (the CLR knows, but that info isn't
exposed to you) that are held on any class (or in any variable).
 
Zytan said:
Shot in the dark, since I know C# doesn't have macros, and thus can't
have a stringizer operator, but I know that you can get the name of
enums as strings, so maybe you can do the same with an ordinary
variable (like an int) somehow. Is it possible? int.ToString()
returns the value of the int as a string, not the name, so I am
thinking 'no'.

Zytan

I suppose that it might be possible to use reflection to get the name,
but why? What are you planning to use it for?
 
Shot in the dark, since I know C# doesn't have macros, and thus can't
have a stringizer operator, but I know that you can get the name of
enums as strings, so maybe you can do the same with an ordinary
variable (like an int) somehow. Is it possible? int.ToString()
returns the value of the int as a string, not the name, so I am
thinking 'no'.

Zytan

In general, no, see Nicholas' response.

A few further points:

1. It is possible to figure out the name of the fields in a type using
Reflection by calling the Type.GetFields() method. That's because
these names form a part of the assembly's metadata. That's very
different from figuring out the name of an instance of the type though
- indeed an instance may not even have a name, it might be living as
an element in a dictionary for example.

2. It is not possible to figure out the name of a local variable
because their names are not compiled into the assembly's metadata.


However, both Reflector and ILDASM *can* get the names of local
variables if the PDB file is available. (Don't even go there, you
don't want to do this!)
 
What are you attempting to do that you need this behavior?

Two things:

1. I want a function like Write(i) which will contstruct the string "i
= 45.", where 45 is the value that i is. This is for debugging, and
saves typing WriteLine("i = "+i); With macros and a stringizing
operator, this can be easily, but C# does not support this.

2. I want to get the name of a class. Again for debugging. I have a
WriteLine method that will state who called it by going up the call
stack: caller -> writeline. But, I have wrappers for this WriteLine
method, again to save typing (this is debugging, remember, so I like
to speed things up), and this wrapper exists between the caller and
the ending function: caller -> wrapper -> writeline. So, you can see
that I have to know how far back up the callstack to go. If I had the
class name, I could go until I am out of the class, and get 'caller'
every time.

Zytan
 
To my best knowledge C# does not have anything
similar to macro and stringifier operator.

No, it doesn't, as I stated, I know this. But, I thought maybe
there's another way.
What you can get for enums is the string representation
of the value not of the variable name.

I meant that it returns a string that is equivalent to what you type
in code. I didn't mean to imply it returns the hidden integer that
exists inside (that you don't have access to unless you explicitly
type cast it). Thus, the value returned is exactly the 'value' you
must type in code (not the hidden value that, for the most part, you
shouldn't ever see or use). This is precisely what I want for a
variable of type int. I want "i" from a variable "int i;", just as I
get "Google" from "MyEnum.Google"

Zytan
 
This isn't correct. There is a one-to-many relationship between a class
and the variables that can have a reference to it. That being said, you
can't figure out all the references (the CLR knows, but that info isn't
exposed to you) that are held on any class (or in any variable).

What isn't correct? Sorry, Nicholas, I don't follow you at all. I am
not looking for references, or multiple references, and I don't care
about any of the internals. I just want to get a string "i" if my
variable is named "i", regardless of what class or function or inner
loop it is declared in. I know it's probably impossible. Like I
said, just a shot in the dark, just in case.

Zytan
 
I suppose that it might be possible to use reflection to get the name,
but why? What are you planning to use it for?

Ah, reflection, I know so little about this. I want it for debugging
purposes, to quickly write out a variable and its value, instead of
labouriously typing in WriteLine("i = "+i); each time. Please see
more detailed answer to your question in an another reply.

Zytan
 
In general, no, see Nicholas' response.

Thought so.
A few further points:

1. It is possible to figure out the name of the fields in a type using
Reflection by calling the Type.GetFields() method. That's because
these names form a part of the assembly's metadata. That's very
different from figuring out the name of an instance of the type though
- indeed an instance may not even have a name, it might be living as
an element in a dictionary for example.

Right. And I want information on the instance. I don't even really
care about the type itself (as long as it supports ToString(), which
all types do).
2. It is not possible to figure out the name of a local variable
because their names are not compiled into the assembly's metadata.
Ok.

However, both Reflector and ILDASM *can* get the names of local
variables if the PDB file is available. (Don't even go there, you
don't want to do this!)

Well, it's just for debugging, so I may want to go there. It's
nothing that'll exist in production code. But, I think you're warning
me that this is a seriously complex solution to a simple matter.
However, if I solved it, I could throw it into a black box and lock it
and never open it again.

Thanks for your reply,

Zytan
 
2. I want to get the name of a class.

this.Name works for instance classes. I need it for a static class.

Zytan
 
2. I want to get the name of a class.
this.Name works for instance classes. I need it for a static class.

Solution:

System.Diagnostics.StackTrace callStack = new
System.Diagnostics.StackTrace();
System.Diagnostics.StackFrame frame = callStack.GetFrame(0);
System.Reflection.MethodBase method = frame.GetMethod();
string name = method.DeclaringType.Name;

Zytan
 
Zytan,

Assume you had a class, MyClass, and this:

MyClass a = new MyClass();
MyClass b = a;

DoSomething(a);

In DoSomething, you have the reference to a, but you can't really unwind
back to a, since a or b both point to it. The logic doesn't make sense.
Also, what do you do when you pass in "new MyClass()", there is no variable
there to work back to. What do you do in that case?
 
MyClass a = new MyClass();
MyClass b = a;

DoSomething(a);

In DoSomething, you have the reference to a, but you can't really unwind
back to a, since a or b both point to it. The logic doesn't make sense.
Also, what do you do when you pass in "new MyClass()", there is no variable
there to work back to. What do you do in that case?

Well, in this case, let's say it was defined like so:

void DoSomething(MyClass x)
{
WriteValue(x);
}

I'd want it to write "x = ...", where ... = x.ToString(). So, I'd
want the string "x", not "a" or "b".

I guess even in this case the WriteValue() function needs to go back
one to get the value of x within its caller, DoSomething. It's within
this and each other function that you must acquire the name of its
variables, not within WriteValue(), since it's already lost by then.
This is where macros are needed, so you can inject the same code in
multiple places by write it only once. So, I think this is
unsolvable, due to lack of macros. Even if we were dealing with value
types, the same holds true.

Zytan
 
Zytan said:
Ah, reflection, I know so little about this. I want it for debugging
purposes, to quickly write out a variable and its value, instead of
labouriously typing in WriteLine("i = "+i); each time. Please see
more detailed answer to your question in an another reply.

Zytan

But using reflection to get the name will be very much more typing than
just typing the name.

As you want the name of a local variable, you can't put the code in a
method, as calling a method with the variable as argument would only
send the value of the variable, not the variable itself.
 
But using reflection to get the name will be very much more typing than
just typing the name.

As you want the name of a local variable, you can't put the code in a
method, as calling a method with the variable as argument would only
send the value of the variable, not the variable itself.

Yup, I've come to that conlcusion in another post. This is where
macros are needed -- to insert large amounts of code in lots of
places, but to only have ONE copy of this code, AND to let you only
type very little code in each location to make use of it. It cannot
be done without macros. It's too bad C# didn't have just a little
support for them.

Zytan
 
Zytan said:
Yup, I've come to that conlcusion in another post. This is where
macros are needed -- to insert large amounts of code in lots of
places, but to only have ONE copy of this code, AND to let you only
type very little code in each location to make use of it. It cannot
be done without macros. It's too bad C# didn't have just a little
support for them.

Zytan

Well, this is one of the few cases where macros could actually be useful.

Generally they are not needed at all, so they would mostly be misused if
available. I believe that not including macros in C# was a good design
decision after all.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top