3

Basically as stated in the title, if I do this:

private const string TYPEOF_STRING = typeof(String).FullName;

Why does it give me the error of:

The expression being assigned to 'Cognitronics.Generic.CloudClient.TYPEOF_STRING' must be constant

EDIT:

It seems we have conflicting answers here and in the thread Habib linked too. Here everyone has said that it is not a compile time constant, whereas in the other thread everyone says it is. This has just made me even more confused so I would like to re-ask which is it?

TheLethalCoder
  • 6,668
  • 6
  • 34
  • 69
  • 1
    Hmm... isn't that quite self-explanatory? – Rob May 06 '15 at 13:24
  • 2
    @Robert, clearly not, otherwise why would the OP have asked his question? Restriction the "const" keyword to compile-time only constants is a language-specific feature. – David Arno May 06 '15 at 13:30
  • @Robert, actually it is not, [`typeof` is resolved at compile time](http://stackoverflow.com/a/139611/961113) – Habib May 06 '15 at 13:31
  • @Habib if it is resolved at compile why doesn't it work then? Or am I being daft? – TheLethalCoder May 06 '15 at 13:41
  • @habib typeof(T) is not compile time constant. It depends. `Type foo(){ return typeof(T); }` – Rune FS May 06 '15 at 13:52

4 Answers4

13

The value of

typeof(String).FullName 

is not a compile time constant, code has to execute to know this value.

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
Justin Harvey
  • 14,446
  • 2
  • 27
  • 30
1

Const means it is constant at compile time and your code needs to run

Use readonly if you want it at run time.

As stated in official site :-

although a const field is a compile-time constant, the readonly field can be used for run-time constants, as in this line: public static readonly uint l1 = (uint)DateTime.Now.Ticks;

And you have just learned one frequently asked interview question ;)

Neel
  • 11,625
  • 3
  • 43
  • 61
0

typeof(string) returns an object of type System.Type and you are accessing a property of that object. Objects don't exist at compile time, so the value of their properties can't be determined to be a constant at compile time. Fullname being an abstract property also mean that there's no way to ensure that Fullname is a constant. So even knowing that the first expression will always yield the same result is not enough to determine that the value of Fullname is a constant

The below is the IL produced for typeof(int)

ldtoken int32
call class [mscorlib]System.Type
     [mscorlib]System.Type::GetTypeFromHandle(valuetype
     [mscorlib]System.RuntimeTypeHandle)

which includes a call to a method and therefore is clearly not constant.

Rune FS
  • 21,497
  • 7
  • 62
  • 96
0

To use the const keyword, the compiler must be able to compute the value assigned at compile time. If it's computed at run time, then the readonly keyword should be used.

Both are constants, in so far as the value cannot be changed.

So to declare your constant, use:

private readonly string typeOfString = typeof(String).FullName;
David Arno
  • 42,717
  • 16
  • 86
  • 131