Declaring constants with the nameof() the constant as the value
Asked Answered
T

3

11

Scenario

I have a class for declaring string constants used around a program:

public static class StringConstants
{
    public const string ConstantA = "ConstantA";
    public const string ConstantB = "ConstantB";
    // ...
}

Essentially, it doesn't matter what the actual value of the constant is, as it used when assigning and consuming. It is just for checking against.

The constant names will be fairly self-explanatory, but I want to try and avoid using the same string values more than once.


What I would like to do

I know that nameof() is evaluated at compile-time, so it is entirely possible to assign the const string's value to the nameof() a member.

In order to save writing these magic strings out, I have thought about using the nameof() the constant itself.

Like so:

public static class StringConstants
{
    public const string ConstantA = nameof(ConstantA);
    public const string ConstantB = nameof(ConstantB);
    // ...
}

Question...

I guess there is no real benefit of using the nameof(), other than for refactoring?

Are there any implications to using nameof() when assigning constants?

Should I stick to just using a hard-coded string?

Thaddeusthaddus answered 30/11, 2016 at 12:43 Comment(8)
nameof provides compile time safetyUltramicroscopic
Sadly, not supported.Vinson
@PauloMorgado - I'm not sure what you mean. What's not supported?Thaddeusthaddus
OOPS!!! My bad! What's not supported is assigning a variable with nameof itself - var c = nameof(c);Vinson
The only downside is it slows down your build for some fractions of seconds to get the symbol and its name. Other than that, it's just a string.Vinson
@PauloMorgado: in case you're interested, the "not supported" case is #7031.Thickknee
Yes @JeroenMostert. I had misread the code in the question.Vinson
There was a related question on Software Engineering Stack Exchange where the question suggested an alternative of making null consts.Brockman
T
4

Whilst I think the use of nameof is clever, I can think of a few scenarios where it might cause you a problem (not all of these might apply to you):

1/ There are some string values for which you can't have the name and value the same. Any string value starting with a number for example can't be used as a name of a constant. So you will have exceptions where you can't use nameof.

2/ Depending how these values are used (for example if they are names of values stored in a database, in an xml file, etc), then you aren't at liberty to change the values - which is fine until you come to refactor. If you want to rename a constant to make it more readable (or correct the previous developer's spelling mistake) then you can't change it if you are using nameof.

3/ For other developers who have to maintain your code, consider which is more readable:

public const string ConstantA = nameof(ContantA);

or

public const string ConstantA = "ConstantA";

Personally I think it is the latter. In my opinion if you go the nameof route then that might give other developers cause to stop and wonder why you did it that way. It is also implying that it is the name of the constant that is important, whereas if your usage scenario is anything like mine then it is the value that is important and the name is for convenience.

If you accept that there are times when you couldn't use nameof, then is there any real benefit in using it at all? I don't see any disadvantages aside from the above. Personally I would advocate sticking to traditional hard coded string constants.

That all said, if your objective is to simply to ensure that you are not using the same string value more than once, then (because this will give you a compiler error if two names are the same) this would be a very effective solution.

Toxemia answered 31/10, 2018 at 16:42 Comment(1)
Thanks for your helpful insight, Brian! Readability is a huge thing for me, along with the ability for other developers to easily understand what's going on. Probably more important for others to consider, is about refactoring, where a constant is used for data access - you wouldn't want to rename the constant and break that (albeit the sample above is scoped to just the app code). I'm inclined to agree with point 1, but would argue most compilers/IDEs would stop you in your tracks trying to define a member starting with a number, anyway - still, a very valid point.Thaddeusthaddus
S
2

Using the nameof() operator with public constant strings is risky. As its name suggests, the value of a public constant should really be constant/permanent. If you have public constant declared with the nameof() and if you rename it later then you may break your client code using the constant. In his book Essential C# 4.0, Mark Michaelis points out: (Emphasis is mine)

public constants should be permanent because changing their value will not necessarily take effect in the assemblies that use it. If an assembly references constants from a different assembly, the value of the constant is compiled directly into the referencing assembly. Therefore, if the value in the referenced assembly is changed but the referencing assembly is not recompiled, then the referencing assembly will still use the original value, not the new value. Values that could potentially change in the future should be specified as readonly instead.

Synchroflash answered 11/1, 2023 at 7:7 Comment(0)
B
1

I think nameof() has 2 advantages over a literal strings:

1.) When the name changes, you will get compiler errors unless you change all occurences. So this is less error-prone.

2.) When quickly trying to understand code you didn't write yourself, you can clearly distinguish which context the name comes from. Example:

ViewModel1.PropertyChanged += OnPropertyChanged; // add the event handler in line 50

...

void OnPropertyChanged(object sender, string propertyName) // event handler in line 600
{
    if (propertyName == nameof(ViewModel1.Color))
    {
         // no need to scroll up to line 50 in order to see
         // that we're dealing with ViewModel1's properties
        ...
    }
}
Bop answered 14/12, 2022 at 14:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.