1

I was writing this piece of code:

public const int MAJOR_VERSION = 3;
public const int MINOR_VERSION = 3;
public const string VERSION_STRING = $"v.{MAJOR_VERSION}{MINOR_VERSION}";

And, maybe not surprisingly, the compiler was complaining:
"The expression being assigned to VERSION_STRING must be constant"

I understand that const expressions are meant to be propagated by the compiler, but in this particular case, the string can very easily be statically created because it depends only on other constants.

So perhaps someone can explain to me why this is not already a feature of the language? Or maybe even, why it's silly of me to ask such a question..

Thanks in advance. :)

alexpanter
  • 1,222
  • 10
  • 25
  • `$"..."` is `string.Format/Concat` method call ... so it's not constant ... – Selvin Jan 23 '20 at 10:14
  • See https://github.com/dotnet/csharplang/issues/2951 – canton7 Jan 23 '20 at 10:16
  • https://weblog.west-wind.com/posts/2016/Dec/27/Back-to-Basics-String-Interpolation-in-C. "At first blush interpolated strings look like an easy way to create string templates that evaluate expressions. But it's important to understand that String Interpolation in C# is merely compiler generated syntactic sugar that dynamically generates string.Format() code with compile time expressions that are parameterized." – Charleh Jan 23 '20 at 10:16
  • 2
    Does this answer your question? [Why does interpolating a const string result in a compiler error?](https://stackoverflow.com/questions/39451921/why-does-interpolating-a-const-string-result-in-a-compiler-error) which is first result of googling: "C# string must be a constant interpolation" – Selvin Jan 23 '20 at 10:19

4 Answers4

3

You have this error because the $ symbol in front of a string is a shortcut for calling String.Format(). String.Format() being a method, its return value cannot be stored in a constant.

nalka
  • 1,894
  • 11
  • 26
2

When we use const keyword, then the values of string interpolation must be a compile-time constant. Using a string interpolation requires .NET code to execute which can only occur when the application is running, not during compile time.

So instead of const you can use static readonly:

public const int MAJOR_VERSION = 3;
public const int MINOR_VERSION = 3;
public static readonly string  VERSION_STRING = $"v.{MAJOR_VERSION}{MINOR_VERSION}";
StepUp
  • 36,391
  • 15
  • 88
  • 148
0

The string you are trying to set is not a constant value, because it is derived from other variables/constants.

Try static readonly instead

public static readonly string VERSION = $"v.{MAJOR_VERSION}{MINOR_VERSION}";
nalka
  • 1,894
  • 11
  • 26
jason.kaisersmith
  • 8,712
  • 3
  • 29
  • 51
  • 1
    `public const string FOO = "bar";` and `public readonly string FOO = "bar";` are accessed differently. for `const`, you use `ClassName.FOO`. For `readonly`, you use `instantiatedObject.FOO`. `const` is `static`, `readonly` is part of instance – Cid Jan 23 '20 at 10:22
0

To explain why the C# team couldn't have made this a compile time feature:

The result of $"{}" or string.Format() can vary at runtime depending on the culture of the machine it's running on at the time.

For example see here that the VERSION is a constant but the resulting strings are different.

const double VERSION = 3.3;

string withDots   = String.Format(new System.Globalization.CultureInfo("en-GB"), "{0:N}", VERSION));
// "3.3"

string withCommas = String.Format(new System.Globalization.CultureInfo("fr-FR"), "{0:N}", VERSION));
// "3,3"
Buh Buh
  • 7,443
  • 1
  • 34
  • 61