Replies: 20 comments
-
I like some of this. |
Beta Was this translation helpful? Give feedback.
-
I want to lend support to getting the current member name in a non-specific way. It seems that the same syntax should work regardless of the member type. Within an instance member one can get the current class name without needing to adapt nameof() by using this.GetType().Name (and the same goes for DelcaringClass.Name, BaseType.Name...). Static members, etc. (e.g. field initializes), however, do not have this ability. In that context I would find extending nameof() less preferable to extending typeof(). Specifically, by allowing typeof(this), in context where "this" is not allowed, to be syntactically equivalent to typeof(CurrentClass). In my mind at least, this would serve the need while also providing additional utility. |
Beta Was this translation helpful? Give feedback.
-
public static class Current {
public static string MemberName([CallerMemberName] string name = null) => name;
}
...
public void Foo() {
Console.WriteLine(Current.MemberName());
} |
Beta Was this translation helpful? Give feedback.
-
All of those are run-time solutions though. Proper nameof support would be compile-time. |
Beta Was this translation helpful? Give feedback.
-
Why? It will just be inlined by the entire system. Why do we need language support (enormously costly) when there is a completely reasonable library solution out there? Remember that features start at a huge point deficit. They need to give enormous value to justify making it into the language. Given that you can write a 3 line library and that gets the job done, i can't possibly imagine why we'd take a language feature here. |
Beta Was this translation helpful? Give feedback.
-
Because if it isn't a compile-time constant, you would not be able to use it, for example, as the default value for a parameter. |
Beta Was this translation helpful? Give feedback.
-
Every time I look at code that uses nameof(), I'm given the impression of a feature that's almost a good idea, but which in reality doesn't appear to deliver on its potential value, because nameof(CurrentMethod) is almost universally what it is used for. This usage leads to bugs. I came to this discussion because I just finished fixing such a bug, due to a manual "extract method" refactoring. ReSharper, for example, proliferates these bugs and prolongs their life because it encourages the use of nameof() instead of a library function that actually does what's needed (i.e. return the current method name), giving the illusion of solving a maintenance problem. Ostensibly, changing the language to add nameof() met the towering bar for adding a feature. What was the reasoning behind adding that feature? Can we not simply reference that reasoning in justifying the addition of nameof(currentClass/Method)? To the extent that nameof() wasn't a regretful addition, the case for this feature request, to have the nameof() feature do what it was intended to do, shouldn't need to be argued from scratch. When I look at MSDN for nameof(), I see nothing but examples of nameof([currentMethod]), so I don't think I'm wrong about the intent. The implementation just doesn't deliver. Note: Two of the linked issues in this discussion explicitly ask for "name of current class" in addition to "name of current method". We would still need a reasonably-performant library method to satisfy that leg of the request, if "library method" is going to be a suitable justification for leaving it out of the language. I think the implementation can be done with the StackFrame class, but I don't know whether that can be considered performant. |
Beta Was this translation helpful? Give feedback.
-
@johndog See my example on how you can easily and cheaply get the current member's name. It won't be a constant. But i don't think it not being a constant is a large enough problem to limit the viability of using the solution i've provided. |
Beta Was this translation helpful? Give feedback.
-
@CyrusNajmabadi Yes, I saw this example, but I still think the request is important. For one thing, as I wrote, that still doesn't address the request for nameof(CurrentClass). I imagine it can be implemented, but I have doubts about the performance. I agree that const-ness does not seem to be that big of a problem, as the need for const can usually be avoided. The bigger issue is that I expect developers will continue to be misled by the existence of the language feature, and that they will continue to overlook the duplication they are habitually writing into their code; rather than a best-practice, we will continue to have a best-kept-secret. To combat this, we can ask tool developers like JetBrains to fix ReSharper to encourage the use something like Current.MemberName(), and we can fix the MSDN article to discourage the use of nameof() for referencing the current method. But I'd rather just see the language changed so that it follows its own implied objectives to completion. If nameof(method) is intended to help programmers avoid bugs resulting from duplication by permitting a symbolic reference to a method's name, then it should help programmers avoid bugs resulting from duplication by providing a way to symbolically reference the name of the current method/class/[namespace]. I don't suppose telemetry is detailed enough to tell us what % of nameof() usages are for nameof(currentMethod)? I expect it would be overwhelming. |
Beta Was this translation helpful? Give feedback.
-
@johndog I decided to run your telemetry experiment on my own code. Here's the breakdown for how nameof is used:
While retrieving the name of the current method and class is occasionally interesting, I find much more value in getting the name of a parameter. |
Beta Was this translation helpful? Give feedback.
-
I've been in a number of codebases large and small and this doesn't ring true. If I had to guess, I'd say it was mostly used for parameters, and second to that, methods/members other than the current method/member. |
Beta Was this translation helpful? Give feedback.
-
@MattDillard Wow that's cool! Can you run it on a few random open source repos? |
Beta Was this translation helpful? Give feedback.
-
@jnm2 Would be cool, but I didn't create a script to do this. I just ran a grep tool and looked through the results manually. I imagine someone could whip up a Roslyn-based program to do the analysis, but I'm a relative newbie to the Roslyn API. I've written a few targeted analyzers, but that's it. |
Beta Was this translation helpful? Give feedback.
-
I can see why people might expect nameof(parameter) to be more prevalent, it does seem logical. In any case, I have to recant any amount of certainty about usage patterns, as clearly it will vary by codebase. I followed Matt's lead in the codebase in which I found the bug: Total: 47 usages
This proportionality was repeated in another codebase I visit. A third codebase was closer to 50/50 between currentContext and parameter. A fourth looked more like @MattDillard 's. All of them suffered from some amount of continued use of string literals where nameof() would have been an improvement, so there are lots of places where nameof() hasn't been discovered yet (i.e. another source of selection bias). I see the following usage patterns for nameof(currentMethod):
Most of the usages I counted in the first codebase were in the third category. |
Beta Was this translation helpful? Give feedback.
-
I found that this issue pops up a bit when I use Infer.Net. E.g., |
Beta Was this translation helpful? Give feedback.
-
idea: float a = default; // same as default(float) -- current shorthand
string b = nameof; // same as nameof(b) -- proposed shorthand I realize a few cons: It may be a tad confusing with the |
Beta Was this translation helpful? Give feedback.
-
Under what circumstances would |
Beta Was this translation helpful? Give feedback.
-
@HaloFour I use it often when working with unity to define symbols that reflect editor values. Basically anywhere where you define a constant string you could use it. We would also use these at work for db strings. I usually have a static class somewhere chock full of em. May be style, though. |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
@HaloFour I've thought of this as common. Usually string constants equal to the member name. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
@comdiv commented on Wed Nov 25 2015
For now:
In second case it fail with "Cannot use local variable '_s' before it is declared ".
I understand that problem is scope and renaming - right side knows outer scope.
My suggestion - add context-bound nameof() operator - for example
nameof(var)
,nameof(void)
andnameof(class)
. Checked - for now allthis forms are compile error - so they can be used.
from my point of view:
Profit:
It's better for refactoring without tools - we not require replacing in several places.
It's allow to reference left side variable
It's good for logs, exception formating - code became more readable and avoid usual copy-paste errors that are common for such code parts:
It's good for code generation - we not require control all names if just require generate some logging / serialization logic
It's good in custom serialize-deserialize while nameof(var) can be used
It's not breaking change.
@alrz commented on Wed Nov 25 2015
C# Design Meeting Notes for Mar 4, 2015
#766
@comdiv commented on Wed Nov 25 2015
nameof is operator to kill doubling, ambiguity and magic-strings - think it should be extended
@m0sa commented on Thu Feb 04 2016
+1 would love to see this
@jrmoreno1 commented on Mon Feb 08 2016
I found this by looking to see if someone had already reported a need for nameof(void) -- I have several projects where that would make adding properties much easier; the property references a resource that is supposed to have the same name (config file or resources), I could then use the same code for all of them, just changing the property name and it would work. While nameof(property) is better than "property", it is still a bit fragile because of copy/paste/edit (or rather not editing).
@comdiv commented on Wed Feb 10 2016
+1
resource idea is very good, I think - it can be even with localization support.
@jrmoreno1 commented on Wed Jul 20 2016
An additional usage that might be beneficial (encountered just today) is referencing a parent class or namespace -- but I can't think of a good syntax for it.
Update: on thinking about it, a good syntax might be
Console.WriteLine(NameOf(void, Namespace);
Console.WriteLine(NameOf(void, Class);
Console.WriteLine(NameOf(void, Method);
Console.WriteLine(NameOf(void, Property);
Console.WriteLine(NameOf(void, Parent); // For nested class
Console.WriteLine(NameOf(void, Base); // For class that this class inherits from
Possibly even
Console.WriteLine(NameOf(void, Type);
Beta Was this translation helpful? Give feedback.
All reactions