How to stop C # from replacing a constant variable with their values?

We have a project compiled into a DLL called consts.dll, which contains something like:

public static class Consts { public const string a = "a"; public const string b = "b"; public const string c = "c"; } 

We have several projects of this kind, each of which is compiled into a DLL with the same name (consts.dll), and we replace them as needed. We have another class that uses these constants:

 public class ConstsUser { string f() { return Consts.a; } } 

Unfortunately, Consts.a optimized for "a", so even if we replace the implementation of Consts.dll, we still get "a" instead of the correct value, and we need to recompile ConstsUser . In any case, so that the optimizer does not replace constant variables with its values?

+60
optimization c #
Jan 09 '14 at 14:21
source share
2 answers

I think using static readonly modifiers suits your needs:

 public static class Consts { public static readonly string a = "a"; public static readonly string b = "b"; public static readonly string c = "c"; } 

Constants are hardcoded on the call site, so this is your problem. The readonly static variable can only be changed in the variable declaration or static constructor of the Consts class, and it will not be included in the call site.

+116
Jan 09 '14 at 14:22
source share

From CLR book via C #

When the code refers to a constant character, compilers look for the character in the metadata of the assembly, which defines the constant, extract the value of the constants and embed the value in the emitted intermediate link Language (IL) . Because the constant value is embedded directly in the code, the constants do not require memory to be allocated to them at run time . In addition, you cannot get the address of a constant, and you cannot pass a constant by reference. These restrictions also mean that constants do not have a good history with the version of the cross-assembly, so you should use them only when you know that the value of the symbol will never change .

As we can see, using const has its advantages when we know that the meaning of a symbol will never change. It can run faster because the CLR does not need permission.

In fact, after assembling the assembly of the application, the assembly of the DLL is not even loaded at run time and can be deleted from the disk, because the compiler does not even add the reference to the assembly of the DLL in the application metadata.

As suggested by @Sergey Berezovskiy, we could use static readonly if you need the CLR to resolve the value dynamically at runtime . This affects performance, but there is another advantage.

In addition, the field can have any data type , so you do not need to limit your compilers to built-in primitive types (since you do it for constants).

+35
Jan 09 '14 at
source share



All Articles