46

How to declare a local constant in C# ?

Like in Java, you can do the following :

public void f(){
  final int n = getNum(); // n declared constant
}

How to do the same in C# ? I tried with readonly and const but none seems to work.

Any help would be greatly appreciated.

Thanks.

Mechanical snail
  • 29,755
  • 14
  • 88
  • 113
missingfaktor
  • 90,905
  • 62
  • 285
  • 365
  • 16
    This is the most annoying omission from C# in my short time using it. I use const on local variables in C++ all the time for my own safety, sanity, and readability. – pauldoo May 20 '10 at 10:16
  • http://stackoverflow.com/questions/443687/why-does-c-sharp-disallow-readonly-local-variables – Mauricio Scheffer Jul 26 '12 at 14:57
  • @MauricioScheffer, thanks for the link. Though now if I have to write something for .NET, I'll most certainly be using F#. :-) – missingfaktor Jul 26 '12 at 15:47

7 Answers7

28

In C#, you cannot create a constant that is retrieved from a method.

Edit: dead link http://msdn.microsoft.com/en-us/library/e6w8fe1b(VS.71).aspx

This doc should help: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/const

A constant expression is an expression that can be fully evaluated at compile time.

Community
  • 1
  • 1
Eric Dahlvang
  • 8,252
  • 4
  • 29
  • 50
  • 25
    Well, that sucks. :/ – Mateen Ulhaq Mar 23 '16 at 21:17
  • 12
    Brutal. I should not only be supported, it should be the default. – andyczerwonka Sep 03 '16 at 16:59
  • 5
    `final` and `const` have different meanings. In C#, a `const` value must be known at compile time. The real issue is that C# does not support local `readonly` variables, which is too bad because they'd be handy. – Nick Jul 18 '17 at 20:47
  • @Nick, in c++ it is not necessary that local const must be known at compile time. – Werner Erasmus May 29 '19 at 09:37
  • While const in C# must be assigned constant values known at compile time (or evaluate-able at compile time), there's no reason why at runtime, something like readonly for properties, could also be applied to locals, am I wrong? AFAIK, readonly is enforced at runtime in C# for properties (even though it's an error at compile time as well). We could have local `var readonly id = GetId();` for example. Even `var const id = -1;`, which is basically a literal that becomes substituted by its value. – Paul-Sebastian Manole Apr 18 '22 at 14:12
  • not sure why this is the accepted answer. for me, the answer from @TamasCzinege looks well-explained and helpful. should check the answer https://stackoverflow.com/a/2054775/9195902. – Yas Ikeda Mar 01 '23 at 01:03
20

Declare your local variable as an iteration variable. Iteration variables are readonly (You didn't ask for a pretty solution).

public void f() 
{
  foreach (int n in new int[] { getNum() }) // n declared constant
  {
    n = 3; // won't compile: "error CS1656: Cannot assign to 'n' because it is a 'foreach iteration variable'"
  }
}
ZunTzu
  • 7,244
  • 3
  • 31
  • 39
8

I'm not sure why readonly and const didn't work for you since these are the keywords you need. You use const if you have a literal (except for array literals) and readonly otherwise:

public void f()
{
    const int answer = 42;
}

private readonly int[] array = new int[] { 1, 2, 3, 4 };
private readonly DateTime date = DateTime.Now;
public void g()
{
    Console.WriteLine(date.ToString());   
}

readonly only works on class level (that is, you can only apply it to fields). Also as a consequence of const requiring a literal, it's inherently static while a readonly field can be either static or instance.

Tamas Czinege
  • 118,853
  • 40
  • 150
  • 176
  • 2
    It's important to note that creating a readonly instance of a reference type only means that the reference itself can't be changed; the object can still be modified normally (unless the type is immutable, like String). – Kevin Kibler Jan 13 '10 at 06:18
  • 3
    The answer to **your** question is simple -- none of them (const, readonly) would work in a given example. – greenoldman Jan 13 '10 at 07:47
6

As of 2018-10-02, it isn't possible to have a readonly local in c#, but there is an open proposal for that feature that has ongoing discussion.

This article provides a useful summary.

afk
  • 358
  • 2
  • 11
4

There is a sort of workaround that requires ReSharper. You can't get readonly locals, but you can at least detect mutated ones and color them differently.

Use the Fonts and Colors item Resharper Mutable Local Variable Identifier.

For me, I have locals colored grey, and then I chose a bold white for the mutated variables (this is with a dark theme). This means that any variable that is written to more than once shows up bright compared to regular ones. You can then do what you can to try to avoid having a mutated variable, or if the method really does require one then it will at least be highlighted.

Dave Cousineau
  • 12,154
  • 8
  • 64
  • 80
  • It doesn't work for me. It only shows the loop counters as unmutable, everything else is mutable, no matter how many writes. I guess my Resharper is too old :-) – Xan-Kun Clark-Davis May 18 '17 at 13:23
  • @Xan-KunClark-Davis it doesn't show what is mutable, it shows what is mutated. anything that is written to exactly once will look normal. anything that is written to twice or more will be highlighted. (oh I guess you said "no matter how many writes"). are you sure? something like `int x = 5; x = 3;`, x should change color. I guess it could be the version, yeah. – Dave Cousineau May 18 '17 at 14:59
  • @ Sahuagin Yeah, I get the part that you kinda have to invert it, all locals get highlightet and all mutables get "normaled" again, but still, it doesn't change the color. I will try with a clean project again. – Xan-Kun Clark-Davis May 18 '17 at 20:48
  • Ok, I opened a new workspace and tried it again, and it works! Real magic :-) The only thing is, there is one behaviour I do not understand but it would be too complicated to explain here. – Xan-Kun Clark-Davis May 18 '17 at 21:13
  • OMG! I really love it now :-) – Xan-Kun Clark-Davis May 18 '17 at 21:14
1

In the example you gave, you need to declare the variable as static, because you're initializing it with a method call. If you were initializing with a constant value, like 42, you can use const. For classes, structs and arrays, readonly should work.

Neil T.
  • 3,308
  • 1
  • 25
  • 30
0

The const keyword is used to modify a declaration of a field or local variable.

From MSDN.

Since C# can't enforce "const correctnes" (like c++) anyway, I don't think it's very useful. Since functions are very narrwoly scoped, it is easy not to lose oversight.

Johannes Rudolph
  • 35,298
  • 14
  • 114
  • 172
  • I must point out however, that eric dahlvang is still right about why const didn't work in your case. – Johannes Rudolph Jan 13 '10 at 06:40
  • 1
    "Since functions are very narrwoly scoped, it is easy not to lose oversight." - Why do other languages like C++ and Java provide such mechanism then? – missingfaktor Jan 14 '10 at 05:48
  • Don't know about java, but c++ can enforce true const also on references, what c# can't. I have never seen const used locally anywhere else than in c++. – Johannes Rudolph Jan 14 '10 at 05:59
  • _“Since functions are very narrwoly scoped, it is easy not to lose oversight.”_ — Not true. Using constants as much as possible is actually a main trait of functional programming. — _“I have never seen const used locally anywhere else than in c++”_ — When I was programming C++ I was using `const` all the the time. On parameter, return values, local variables. Everything what could be declared const i declared const. – Martin Oct 04 '19 at 06:57
  • I cannot agree with the statement that it's not useful. In fact, it's super useful. If I see a local const variable I immediately know that I won't be surprised later. It does wonders for readability. – Christian Rizov Jul 05 '20 at 15:35