Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Advantages of using const instead of variables inside methods

Whenever I have local variables in a method, ReSharper suggests to convert them to constants:

// instead of this: var s = "some string"; var flags = BindingFlags.Public | BindingFlags.Instance;  // ReSharper suggest to use this: const string s = "some string"; const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance; 

Given that these are really constant values (and not variables) I understand that ReSharper suggest to change them to const.

But apart from that, is there any other advantage when using const (e.g. better performance) which justifies using const BindingFlags instead of the handy and readable var keyword?

BTW: I just found a similar question here: Resharper always suggesting me to make const string instead of string, but I think it is more about fields of a class where my question is about local variable/consts.

like image 242
M4N Avatar asked Apr 29 '11 15:04

M4N


People also ask

Why would you use a constant instead of a variable?

Constants are used when you want to assign a value that doesn't change. This is helpful because if you try to change this, you will receive an error. It is also great for readability of the code. A person who reads your code will now know that this particular value will never change.

What is the advantage of using const?

Const is particularly useful with pointers or references passed to a function--it's an instantly understandable "API contract" of sorts that the function won't change the passed object.

What is the advantage of constant variable?

o Constants make our programs easier to read by replacing magic numbers and strings with readable names whose values are easy to understand. o Constants make our program easier to modify. o Constants make it easier to avoid mistakes in our programs.

What are the advantages of using constants in programs?

Constants can make your program more readable. For example, you can declare: Const PI = 3.141592654. Then, within the body of your program, you can make calculations that have something to do with a circle. Constants can make your program more readable.


2 Answers

The compiler will throw an error if you try to assign a value to a constant, thus possibly preventing you from accidentally changing it.

Also, usually there is a small performance benefit to using constants vs. variables. This has to do with the way they are compiled to the MSIL, per this MSDN magazine Q&A:

Now, wherever myInt is referenced in the code, instead of having to do a "ldloc.0" to get the value from the variable, the MSIL just loads the constant value which is hardcoded into the MSIL. As such, there's usually a small performance and memory advantage to using constants. However, in order to use them you must have the value of the variable at compile time, and any references to this constant at compile time, even if they're in a different assembly, will have this substitution made.

Constants are certainly a useful tool if you know the value at compile time. If you don't, but want to ensure that your variable is set only once, you can use the readonly keyword in C# (which maps to initonly in MSIL) to indicate that the value of the variable can only be set in the constructor; after that, it's an error to change it. This is often used when a field helps to determine the identity of a class, and is often set equal to a constructor parameter.

like image 180
landoncz Avatar answered Sep 18 '22 20:09

landoncz


tl;dr for local variables with literal values, const makes no difference at all.


Your distinction of "inside methods" is very important. Let's look at it, then compare it with const fields.

Const local variables

The only benefit of a const local variable is that the value cannot be reassigned.

However const is limited to primitive types (int, double, ...) and string, which limits its applicability.

Digression: There are proposals for the C# compiler to allow a more general concept of 'readonly' locals (here) which would extend this benefit to other scenarios. They will probably not be thought of as const though, and would likely have a different keyword for such declarations (i.e. let or readonly var or something like that).

Consider these two methods:

private static string LocalVarString() {     var s = "hello";     return s; }  private static string LocalConstString() {     const string s = "hello";     return s; } 

Built in Release mode we see the following (abridged) IL:

.method private hidebysig static string LocalVarString() cil managed  {     ldstr        "hello"     ret           }  .method private hidebysig static string LocalConstString() cil managed  {     ldstr        "hello"     ret           } 

As you can see, they both produce the exact same IL. Whether the local s is const or not has no impact.

The same is true for primitive types. Here's an example using int:

private static int LocalVarInt() {     var i = 1234;     return i; }  private static int LocalConstInt() {     const int i = 1234;     return i; } 

And again, the IL:

.method private hidebysig static int32 LocalVarInt() cil managed {     ldc.i4       1234     ret           }  .method private hidebysig static int32 LocalConstInt() cil managed {     ldc.i4       1234     ret      } 

So again we see no difference. There cannot be a performance or memory difference here. The only difference is that the developer cannot re-assign the symbol.

Const fields

Comparing a const field with a variable field is different. A non-const field must be read at runtime. So you end up with IL like this:

// Load a const field ldc.i4       1234  // Load a non-const field ldsfld       int32 MyProject.MyClass::_myInt 

It's clear to see how this could result in a performance difference, assuming the JIT cannot inline a constant value itself.

Another important difference here is for public const fields that are shared across assemblies. If one assembly exposes a const field, and another uses it, then the actual value of that field is copied at compile time. This means that if the assembly containing the const field is updated but the using assembly is not re-compiled, then the old (and possibly incorrect) value will be used.

Const expressions

Consider these two declarations:

const int i = 1 + 2; int i = 1 + 2; 

For the const form, the addition must be computed at compile time, meaning the number 3 is kept in the IL.

For the non-const form, the compiler is free to emit the addition operation in the IL, though the JIT would almost certainly apply a basic constant folding optimisation so the generated machine code would be identical.

The C# 7.3 compiler emits the ldc.i4.3 opcode for both of the above expressions.

like image 20
Drew Noakes Avatar answered Sep 20 '22 20:09

Drew Noakes