views:

1562

answers:

5

Why does C# not allow const and static on the same line? In Java, you must declare a field as 'static' and 'final' to act as a constant. Why does C# not let you declare const's as final?

I make the further distinction that in Java, every interface is public and abstract, whether this is explicitly declared or not. Aren't const's effectively static in nature? WHy does C# balk at this?

+10  A: 

Constants by their nature are static, so that would be redundant.

Greg Ogle
Right, but like I said... Java lets you declare an interface as 'public' and 'abstract'. It's inherent, so it's not an error. So why is it an error in C# if you explicitly denote what is inherent?
Cuga
Reducing unnecessary choice is good idea in general, IMO.
Sake
I'll give you that. I consider your comment to be the best answer so far.
Cuga
In a dictionary sense, constants are static, but in C# static refers to memory allocation, not the value. It's the memory allocation that is static (once, for all instances of the class).
Tim Long
+1  A: 

Because allowing and not requiring modifiers that are inherent can cause confusion. If you see

static const int A = 3
const int B = 5

you may believe that they are 2 different kinds of constants.
Even VB 2008 (which can be very verbose if you wish) doesn't allow that.

ggf31416
That's not the reason (though you may be right about it being confusing). For example, if I declare a field and don't give it any access modifiers, is it public, private, static, internal, what? The default is private, but you don't have to declare that explicitly. The reason static and const can't be used together is because they imply different storage mechanisms and are therefore mutually exclusive.
Tim Long
+10  A: 

const and static really do mean different things, different storage mechanism, different initialisation. static is read/write, therefore must have memory allocated for storage and must be initialised at runtime. A static can be initialised with a literal value or an expression. In contrast, a const must be initialised with a literal value and is immutable. The value is known at compile time so it can be embedded directly in the generated code, therefore requires no storage to be allocated at runtime.

Tim Long
True, const and static mean different things. But 'const' and 'static final'... what's the difference there?
Cuga
The question relates to C# - there is no 'final' keyword in C#.
Tim Long
While the original question was 'const' vs 'static final' (not just static and therefore both are denied 'write' permission), you've convinced me that memory allocation or something along these lines must be the reason.
Cuga
@Tim: true, but there *is* readonly.
Steven Mackenzie
@Steven: const is still different from readonly. Readonly refers to the *reference*, not the *value*. Readonly just means that the reference must always point to the same object. It does not mean that the object's value can't change. Const, on the other hand, does mean that the value is constant.
Tim Long
Thanks @Tim, I didn't really mean const==readonly, but your comment did provoke some thought on just how const/immutable reference types could work - the last piece of the puzzle is this from the language reference: "A constant expression is an expression that can be fully evaluated at compile time. Therefore, the only possible values for constants of reference types are string and null."
Steven Mackenzie
+2  A: 

It is true that a C# const implies static BUT, C# has an equivalent to Java's final keyword in the keyword readonly.

So, in fact, C# allows a const final, it is static readonly in C#.

LWoodyiii
"static readonly" is not the same as "const". A constant will be compiled as is. static readonly will be referened from the original location. If the value may posible change in the future or even at instanation you should use readonly. If it will truly be constant and never change (such as Natural Log, Pi, etc) then const is a good choice. Otherwises you may be better of with "public static readonly"
Matthew Whited
I'm sorry, I was referring to "static final" in Java equals "static readonly" in C# (roughly).
LWoodyiii
+3  A: 

As said before, static final in Java is the same as static readonly in C#. In fact, you are saying that this member is static and its content can't be changed. Also you can specify in both cases the value from static constructor.

But const in C# is completely different thing. It's more along the lines of constants in C (DEFINE directives) but with OOP in mind. It's static because it's constant - every instance would have this constant with the same value, no constructor can set it. Also it's possible that someone would like to access the constant without having to create an instance. When you think about it non-static constant just doesn't make sense. You can almost say that constants are not part of an object - they just use it to provide context, a strong name.

Java doesn't have an equivalent to const. You can read somewhere that static final is equivalent to DEFINE but that's just so vague. Completely different mechanism, nothing in common but in the end result in the code is the same - better maintainability and readability of the code.

You just have to stop thinking about constants in C# as static members because they are not. Think of them as OOP version of DEFINE. When you consider encapsulation only reason for final and readonly fields is to prevent your own code from accidently changing its value. And that doesn't sound like constant to me.

Sumary:

  • final = readonly
  • static final = static readonly
  • N/A = const
CodeRipper