Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I create a string constant by concatenating string and int constants in C#?

I know that I can create new constant strings by concatenating other constant strings:

const string a = "A";
const string ab = a + "B";

Is it somehow possible to create a constant string based on a constant int? For example, the following won't compile:

const int Dpi = 300;
const string DeviceInfo = "<DeviceInfo><Dpi>" + Dpi + "</Dpi></DeviceInfo>";

The expression assigned to MyClass.DeviceInfo must be constant.

I know that I could work around this by

  1. making Dpi a string instead of an int (and int.Parseing it when I need the int value),
  2. adding a second string constant DpiString (and, thus, violating DRY), or
  3. making DeviceInfo a static readonly field instead of a const field.

I'm going to go with option 3, but, out of curiosity, I was wondering if there is some other option that I missed...

like image 591
Heinzi Avatar asked Dec 02 '17 10:12

Heinzi


2 Answers

No, string constants cannot be expressions that are evaluated at runtime.

  • https://github.com/dotnet/csharplang/blob/master/spec/expressions.md#constant-expressions

The following conversions are permitted in constant expressions:

  • Identity conversions
  • Numeric conversions
  • Enumeration conversions
  • Constant expression conversions
  • Implicit and explicit reference conversions, provided that the source of the conversions is a constant expression that evaluates to the null value.

Other conversions including boxing, unboxing and implicit reference conversions of non-null values are not permitted in constant expressions.

Converting an int to a string falls in the "other conversions" which are not permitted, since this requires a call to the ToString() method.

In point of fact, the conversion requires a call to int.ToString() which is defined to use the G10 number format. This depends on the current culture's NumberFormatInfo.NegativeSign so could in principle change. I'm not aware of any default culture which uses anything for the negative sign other than the \u002d hyphen-minus character, but you could certainly set it at runtime to something else if you want to see the world burn.

like image 161
Ben Avatar answered Sep 30 '22 15:09

Ben


You can't do that with const. But what is your main concern here? Do you want to make sure the value will never change, or do you want it to be available at compile time?

If you want to make sure it will never change, you can use either of these:

  1. Readonly field
  2. Readonly property with a field, both encapsulated in a singleton class.
  3. Readonly property concatenating strings at run-time
  4. A static readonly field

But in some use-cases you may want to have the value available at compile-time. In that case you have to make your integer a const string, as you've described in your options 1 and 2.

like image 21
Sepehr Samiei Avatar answered Sep 30 '22 15:09

Sepehr Samiei