Take the 2-minute tour ×

I was plugging away on an open source project this past weekend when I ran into a bit of code that confused me to look up the usage in the C# specification.

The code in questions is as follows:

internal static class SomeStaticClass
    private const int CommonlyUsedValue = 42;

    internal static string UseCommonlyUsedValue(...)
        // some code
        value = CommonlyUsedValue + ...;

        return value.ToString();

I was caught off guard because this appears to be a non static field being used by a static function which some how compiled just fine in a static class!

The specification states (§10.4):

A constant-declaration may include a set of attributes (§17), a new modifier (§10.3.4), and a valid combination of the four access modifiers (§10.3.5). The attributes and modifiers apply to all of the members declared by the constant-declaration. Even though constants are considered static members, a constant-declaration neither requires nor allows a static modifier. It is an error for the same modifier to appear multiple times in a constant declaration.

So now it makes a little more sense because constants are considered static members, but the rest of the sentence is a bit surprising to me. Why is it that a constant-declaration neither requires nor allows a static modifier? Admittedly I did not know the spec well enough for this to immediately make sense in the first place, but why was the decision made to not force constants to use the static modifier if they are considered static?

Looking at the last sentence in that paragraph, I cannot figure out if it is regarding the previous statement directly and there is some implicit static modifier on constants to begin with, or if it stands on its own as another rule for constants. Can anyone help me clear this up?

share|improve this question
Maybe they chose not to allow static because it could lead to confusion: someone seeing "static const foo..." may mistakenly believe that static actually makes a difference, implying that you could remove it and somehow have a non-static const. –  Igby Largeman Apr 13 '10 at 18:14
You get a very decent compiler error message when you try to use static and const together. I think that is good enough. –  Hamish Grubijan Aug 4 '10 at 3:15

4 Answers 4

up vote 34 down vote accepted

Basically, const implies static already, since the value cannot be changed at runtime. There's no reason for you to ever declare static const, since it's already implied, and the language designers decided to make the language syntax reflect that.

The specification language is basically saying "Const is always static, so you can't explicitly say static and const since it's redundant."

share|improve this answer
If that is the case, then why do they allow you explicitly use private on just about everything in the language? –  Nick Larsen Apr 13 '10 at 18:21
Adding private doesn't suggest a different meaning. Here, if the allowed "const variable" and "static const variable", it would suggest that there were non-static const options. Private doesn't define the storage of a variable, but is more of a decorator describing it's accessability - adding or removing it doesn't really change meaning, but adds a descriptive element to the type. –  Reed Copsey Apr 13 '10 at 18:23
By allowing private to be added or left off suggests that there are non-private member options, which there are. :) –  Reed Copsey Apr 13 '10 at 18:24
+1. Private is simply the default accessibility modifier for a class member. static is not the default for constants, it's the only option. –  Adam Robinson Apr 13 '10 at 18:33
@Nick leaving of the access modifier means different things in differrent contexts. The default is not always private. It might be internal. The const is never associated with an instance. How would that work? I'd say it would be very confusing if you could do static const which would imply that you could have an instance constant as well but then I guess if you have a c++ background you might read const as readonly (aka writable once) and then suddenly instanceness makes sense. In C# however const is constant and readonly is well almost readonly :p –  Rune FS Jun 11 '10 at 6:34

UPDATE: This question was the subject of my blog on June 10th, 2010. Thanks for the great question!


Suppose constants are considered to be static. There are three possible choices:

  1. Make static optional: "const int x..." or "static const int x..." are both legal.

  2. Make static required: "const int x..." is illegal, "static const int x..." is legal

  3. Make static illegal: "const int x..." is legal, "static const int x..." is illegal.

Your question is why did we choose (3)?

The design notes from 1999 do not say; I just checked. But we can deduce what was probably going through the language designer's heads.

The problem with (1) is that you could read code that uses both "const int x..." and "static const int y..." and then you would naturally ask yourself "what's the difference?" Since the default for non-constant fields and methods is "instance" unless "static", the natural conclusion would be that some constants are per-instance and some are per-type, and that conclusion would be wrong. This is bad because it is misleading.

The problem with (2) is that first off, it is redundant. It's just more typing without adding clarity or expressiveness to the language. And second, I don't know about you, but I personally hate it when the compiler gives me the error "You forgot to say the magic word right here. I know you forgot to say the magic word, I am one hundred percent capable of figuring out that the magic word needs to go there, but I'm not going to let you get any work done until you say the magic word".

The problem with (3) is that the developer is required to know that const logically implies static. However, once the developer learns this fact, they've learned it. It's not like this is a complex idea that is hard to figure out.

The solution which presents the fewest problems and costs to the end user is (3).

It is interesting to compare and contrast this with other places in the language where different decisions were made.

For example, overloaded operators are required to be both public and static. In this case, again we are faced with three options:

  1. make public static optional,

  2. make it required, or

  3. make it illegal.

For overloaded operators we chose (2). Since the natural state of a method is private/instance it seems bizarre and misleading to make something that looks like a method public/static invisibly, as (1) and (3) both require.

For another example, a virtual method with the same signature as a virtual method in a base class is supposed to have either "new" or "override" on it. Again, three choices.

  1. make it optional: you can say new, or override, or nothing at all, in which case we default to new.

  2. make it required: you have to say new or override, or

  3. make it illegal: you cannot say new at all, so if you don't say override then it is automatically new.

In this case we chose (1) because that works best for the brittle base class situation of someone adds a virtual method to a base class that you don't realize you are now overriding. This produces a warning, but not an error.

My point is that each of these situations has to be considered on a case-by-case basis. There's not much general guidance here.

share|improve this answer
I like your point about static being a "magic word" in this case. Still I don't think that is enough to tip the scales for me, however, option 1 would still be more confusing, and after all the comments in this thread, I can understand the reasoning for 3. The converse of this situation, where the compiler does throw an error if I had tried to make a constant static, would have left me with similar questions. –  Nick Larsen Apr 13 '10 at 20:45
+1 for authority and use the of "magic word". Not necessarily in that order! ;) –  Adam Robinson Apr 13 '10 at 21:33
Coming from the blog: maybe it's just me, but i find that not needing static just confuses me. If i don't see the word static, then i assume that it's an instance variable. It doesn't help that you can access it either way from inside the class (this.MyConstant or MyClassName.MyConstant). Further, i thought the point of statically typed languages was to make more typing without adding expressivity or clarity ;) @Adam Robinson: Surely you meant use of the not use the of ;) –  RCIX Jun 11 '10 at 2:04
@RCIX: Enjoy Yodaspeak often I do. –  Adam Robinson Jun 11 '10 at 2:33

Another reason to disallow declare constants as static is that from CLR point of view the constants are not not stored in memory along with other static fields of the type.

The constants don't have memory address and you cannot get reference to the constant value (the only exception is string constants). At runtime the type holding constant definition won't be loaded if other static/nonstatic members are not referenced. If it is the only type in the assembly, you can even safely delete it's DLL from the disk after compilation.

So, the constants are 'static' only in terms of 'may be referenced from static methods'. Constants do not have any other 'static' properties as other static type members do.

share|improve this answer

It isn't required or allowed because it's redundant. If all const members are static, then only confusion can arise from allowing some of them to be specified as static and some of them not to be.

share|improve this answer
But that was my question, why not force them all to be static? –  Nick Larsen Apr 13 '10 at 18:13
@Adam: But you could require the static keyword, instead of requiring its absence. –  Kent Boogaart Apr 13 '10 at 18:14
Because there's no way for them not to be static. Why require a redundant term? –  Adam Robinson Apr 13 '10 at 18:14
Thats a good point, but leaving off highly descriptive terms is something I would consider confusing (...as I did :) ). –  Nick Larsen Apr 13 '10 at 18:37
@Nick: It doesn't break any language rules; you stated that your objection was that it's leaving out "descriptive" information, but passing by value is descriptive, as is marking the constant as read only; they're also just as redundant as marking a constant static. If you know what const means in C#, then how does it possibly even appear to be breaking any language rules? –  Adam Robinson Apr 13 '10 at 18:52

Your Answer


