8

Possible Duplicate:
get name of a variable or parameter

I want to be able to get a variable's name as a string.

This can be achieved effectively by using a parameterless lambda expression. However, this has a performance overhead, and it's not built-in functionality.

.NET 4.5 has provided CallerMemberNameAttribute to provide a caller's name as a method argument. This gives us a built-in and better (in some cases) way to do this for specific situations.

.NET 4.5 has provided an improvement in this area for a specific context. Is there now also a better^ means to get any variable's name as a string?

As requested, here's a general usage example of what I'd like to achieve:

//Assume 'myVariable' is a local variable, member variable, static member variable, constant, parameter or even a property.
string myVariableName = ...; //This should get the string name of myVariable

^By better, I mean faster, not requiring reflection, built-into .NET or more elegant, but preferably a combination of these.

Community
  • 1
  • 1
Sam
  • 40,644
  • 36
  • 176
  • 219
  • 1
    Wow the caller member name attribute looks cool. I havent heard about it yet. – AbdElRaheim Oct 31 '12 at 08:51
  • 2
    +1, For letting me know about this new Attribute :) – Furqan Safdar Oct 31 '12 at 09:06
  • 1
    as far as I can remember: you can get information on the parameters by using PostSharp (http://www.sharpcrafters.com/) - but for variables... could you give an example of usage? –  Oct 31 '12 at 09:12
  • StackTrace can give any information required, not sure about efficiency... – CapelliC Oct 31 '12 at 09:35
  • @chac, I don't consider that to be any better than the existing approaches. I think it's actually worse; I recall reading that it depends on your build options. – Sam Oct 31 '12 at 09:36
  • @Sam not only build options. The .NET CLR JIT compiler can inline methods regardless the build-target (http://blogs.msdn.com/b/davidnotario/archive/2004/11/01/250398.aspx) ... –  Oct 31 '12 at 09:40
  • your approach is covered by another question here on SO: http://stackoverflow.com/questions/9801624/get-name-of-a-variable-or-parameter if you are after more elegant exception-throwing you might choose my answer ... –  Oct 31 '12 at 09:56
  • @AndreasNiedermair, you haven't answered the question. Regarding the question you linked to, I am asking if there is a better way to solve the problem with the new .NET 4.5 release. That question's accepted answer only covers the lambda expression mechanism I mentioned in the question, and it's not in the context of .NET 4.5 – Sam Oct 31 '12 at 10:01
  • @Sam now your intention is clear, I have to agree :) and that's the reason I've removed my answer. Nevertheless, how can be `string testVariable = "value"; string nameOfTestVariable = MemberInfoGetting.GetMemberName(() => testVariable);` more simplified?! as you elaborate over time you can't expect people to keep up with your edits, though! And I thought the keypoint was *I'm looking for a better way to do this* not *I'm looking for a better way to do this in .NET 4.5* :) Besides that, why do you need .NET 4.5-context? Only to have it, or is it somehow reasonable?! –  Oct 31 '12 at 10:03
  • 3
    What you are asking is code inspection during runtime. You can't do "any better" than reflection. – Dante Oct 31 '12 at 10:13
  • @AndreasNiedermair, the key point really is that I want a _better_ way to do this. I mentioned .NET 4.5 because I already investigated this before .NET 4.5 and found the lambda expression solution to be overall the best option, but after seeing the improvement provided by `CallerMemberNameAttribute`, I don't know if .NET 4.5 has enabled an improved mechanism to achieve this. – Sam Oct 31 '12 at 10:25
  • 2
    @John: of cause you could. Variablenames are known at compiletime, so the designers of the C# language could provide some builtin function to get the name of a variable without using reflection. And thats what the OP was asking for, because they have added the very similar CallerMemberNameAttribute with .NET 4.5 – Jan Oct 31 '12 at 10:25
  • FYI, the LINQ sytntax doesn't use reflection, that's the whole point of using Expression trees; they're fast! They get created during compilation so there's not even any overhead for generating them. – Doctor Jones Oct 31 '12 at 10:43
  • @AndreasNiedermair, by the way, regarding what you said about the lambda expression approach only working for member variables, I did some testing and found that it works for all variables except for `const` ones. (I presume this is because they're inlined at compile-time.) – Sam Oct 31 '12 at 11:20

1 Answers1

3

No there is no better/faster way. I think, the expresseion tree way you have linked is the only way to get to the name of the variable.

The CallerMemberNameAttribute, CallerFilePathAttribute, CallerLineNumberAttribute are the sole new features introduced in .NET 4.5 in that area.

Jan
  • 15,802
  • 5
  • 35
  • 59
  • "Indeed there is no other way than using reflection to get the name of the variable" - that's incorrect. The Expression trees technique doesn't use reflection, they're generated at compile time. The whole point of Expression trees is that they are much quicker than using reflection. – Doctor Jones Oct 31 '12 at 10:47
  • @DoctaJonez: Yes, you are right - its not reflection. I have updated my answer. – Jan Oct 31 '12 at 10:52
  • There is a trick where class-level property static initialization sets the `[CallerMemberName]` to the property name (instead of the method name for local variables). NOTE it does *not* work with anonymous types nor impl/expl operators - they get the method name or ctor. The new `nameof` operator allows rename refactoring while maintaining the performance of a string literal (because it becomes one at compile time). eg `var abc = new MyThing(nameof(abc));` unfortunately this cannot be automatically obtained by the callee without the caller adding code (unlike `[CallerMemberName]`). – Graeme Wicksted Aug 09 '16 at 15:53