Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using consts in static classes

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?

like image 901
Nick Larsen Avatar asked Apr 13 '10 18:04

Nick Larsen


People also ask

Are consts static?

The const keyword converts nothing more but a constant. The specialty of these variables is that they need to have a value at compile time and, by default, they are static. This default value means that a single copy of the variable is created and shared among all objects.

Can static class be inherited in C#?

Static classes are sealed and therefore cannot be inherited. They cannot inherit from any class except Object. Static classes cannot contain an instance constructor. However, they can contain a static constructor.

Can static class have constructor C#?

A static class can only have static members — you cannot declare instance members (methods, variables, properties, etc.) in a static class. You can have a static constructor in a static class but you cannot have an instance constructor inside a static class.

Can static class have non static method in C#?

Static class always contains static members. Non-static class may contain both static and non-static methods. Static class does not contain an instance constructor.


1 Answers

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

why was the decision made to not force constants to use the static modifier if they are considered static?

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.

like image 103
Eric Lippert Avatar answered Oct 12 '22 14:10

Eric Lippert