views:

1102

answers:

6

In .Net why is String.Empty read only instead of a constant? I'm just wondering if anyone knows what the reasoning was behind that decision.

A: 

Because String is a class and therefore cannot be a constant.

Please look at the comments to this question as they contain extra details and discussion of the topic

Garry Shutler
Please, vote down the correct answer. If you Goto Definition, you'll find that it is on the String class and is an instance of String.The fact that it shows as lower case is compiler magic.
Garry Shutler
It wasn't me who downvoted you but in .NET, (unlike in Java) string and String are exactly the same. And yes, you can have string literal constants in .NET
DrJokepu
I didnt DV you, but can you humor me a bit. Are you saying that a Class cannot have constants?
StingyJack
Yes, objects have to use readonly. Only structs can do constants. I think when you use string instead of String the compiler changes the const into a readonly for you. All to do with keeping C programmers happy.
Garry Shutler
tvanfosson just explained it a little bit more verbose. "X cannot be a constant, because the containing Y is a class" was just a little bit too context-free ;)
Leonidas
string.Empty is static property that returns an instance of the String class, namely the empty string, not the string class itself.
tvanfosson
Empty is a readonly **instance** (it's not a property) of the String class.
senfo
Head hurting. I still think I'm right, but now I'm less certain. Research required tonight!
Garry Shutler
The empty string is an instance of the string class. Empty is a static field (not a property, I stand corrected) on the String class. Basically the difference between a pointer and the thing it points to. If it weren't readonly we could change which instance the Empty field refers to.
tvanfosson
Garry, you don't need to do any research. Think about it. String is a class. Empty is an instance of a String.
senfo
There is something I don't quite get: how on earth can the static constructor of the String class create an instance of the String class ? Isn't that some sort of "chicken or the egg" scenario?
DrJokepu
This answer would be correct for nearly any other class but System.String. .NET does a lot of performance special-casing for strings, and one of them is that you CAN have string constants, just try it. In this case, Jeff Yates has the correct answer.
Joel Mueller
As described in §7.18, a constant-expression is an expression that can be fully evaluated at compile-time.
senfo
(continued) Since the only way to create a non-null value of a reference-type other than string is to apply the new operator, and since the new operator is not permitted in a constant-expression, the only possible value for constants of reference-types other than string is null.
senfo
The previous two comments were taken directly from the C# language specification and reiterate what Joel Mueller mentioned.
senfo
I nearly deleted this answer as a much better one came along, but the discussion in these comments is worth keeping.
Garry Shutler
A: 

because a constant will create and object when string.Empty does not

Oscar Cabrero
If string.Empty was/could be a constant then it would create the exact same number of objects as a readonly statement.
Garry Shutler
@Garry: yes, except that a static member cannot be const.
senfo
String.Empty indeed creates an object - just check out the static constructor of the String class with Resharper
DrJokepu
A: 

According to this link, the reason is that by making it a readonly property you save one object creation for maximum efficiency.

mwigdahl
A readonly field and a constant one will always result in one instance being created. However, each time you use "" it creates a new string, which is the point that article was making.
Garry Shutler
@Garry Shutler - which seems wrong, since I remember reading that the compiler "interns" strings, so every time you use "" it refers to the same string instance.
Scott Whitlock
A: 

For all intents and purposes it is constant... unless you know something I don't about how to change it or how to create duplicate instances.

Joel Coehoorn
+29  A: 

The reason that static readonly is used instead of const is due to use with unmanaged code, as indicated by Microsoft here in the Shared Source Common Language Infrastructure 2.0 Release. The file to look at is sscli20\clr\src\bcl\system\string.cs.

The Empty constant holds the empty string value. We need to call the String constructor so that the compiler doesn't mark this as a literal.

Marking this as a literal would mean that it doesn't show up as a field which we can access from native.

I found this information from this handy article at CodeProject.

Jeff Yates
Google is our friend. :)
Jeff Yates
One of the best friends in deed. :)
Ismail
+8  A: 

I think there is a lot of confusion and bad responses here.

First of all, const fields are static members (not instance members).

Check section 10.4 Constants of the C# language specification.

Even though constants are considered static members, a constant-declaration neither requires nor allows a static modifier.

If public const members are static, one could not consider that a constant will create a new Object.

Given this, the following lines of code do exactly the same thing in respect to the creation of a new Object.

public static readonly string Empty = "";
public const string Empty = "";

Here is a note from Microsoft that explains the difference between the 2:

The readonly keyword is different from the const keyword. A const field can only be initialized at the declaration of the field. A readonly field can be initialized either at the declaration or in a constructor. Therefore, readonly fields can have different values depending on the constructor used. Also, while a const field is a compile-time constant, the readonly field can be used for runtime constants, ...

So I find that the only plausible answer here is Jeff Yates's.

bruno conde
+1 for the kind words and clarification regarding C# spec on const and static readonly.
Jeff Yates