Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I change the value of String.Empty?

Tags:

While I understand that changing the value of String.Empty would be a bad idea, I don't understand why I can't do it.

To get what I mean, consider the following class:

public class SomeContext  {      static SomeContext(){}     public static readonly string Green = "Green";     public static readonly SomeContext Instance = new SomeContext();      private SomeContext(){}     public readonly string Blue = "Blue";      public static void PrintValues()     {          Console.WriteLine(new { Green, Instance.Blue, String.Empty }.ToString());     } } 

I have a little console app that tries to manipulate these three readonly fields. It can successfully make Blue and Green into Pink, but Empty stays the same:

        SomeContext.PrintValues();         ///  prints out : { Green = Green, Blue = Blue, Empty = }         typeof(SomeContext).GetField("Blue").SetValue(SomeContext.Instance, "Pink");         typeof(SomeContext).GetField("Green", BindingFlags.Public | BindingFlags.Static).SetValue(null, "Pink");         typeof(String).GetField("Empty", BindingFlags.Public | BindingFlags.Static).SetValue(null, "Pink");         SomeContext.PrintValues();         ///  prints out : { Green = Pink, Blue = Pink, Empty = } 

Why?

Originally, I also asked why String.Empty wasn't a constant. I found the answer to this part of my question on another post and deleted that part of the question).

Note: None of the "duplicates" have a conclusive answer to this problem, that's why I'm asking this question.

like image 840
smartcaveman Avatar asked Nov 13 '13 21:11

smartcaveman


People also ask

Why is string empty not a constant?

string. Empty is a static readonly field, not a literal constant. This precludes its use anywhere that requires a compile-time constant, e.g. attribute constructors and default parameters.

What is the value of string empty?

An empty string is a string instance of zero length, whereas a null string has no value at all. An empty string is represented as "" . It is a character sequence of zero characters. A null string is represented by null .

How do you pass a blank string in Java?

All you need to do is to call equals() method on empty String literal and pass the object you are testing as shown below : String nullString = null; String empty = new String(); boolean test = "". equals(empty); // true System.

Is empty string C++?

To check if a string is empty or not, we can use the built-in empty() function in C++. The empty() function returns 1 if string is empty or it returns 0 if string is not empty. Similarly, we can also use the length() function to check if a given string is empty or not. or we can use the size() function.


1 Answers

You can't change it because you have .NET 4.5 on your machine. Just change the Framework Target setting of your project to 3.5 and you'll see it works.

The CLR has built-in knowledge of String.Empty. You'll for example see with a Reflector or the Reference Source that the System.String class never initializes it. It is done during CLR startup. Exactly how 4.5 prevents the modification from being visible is a bit hard to tell. You actually did modify the field, just add this line of code:

  var s = typeof(String).GetField("Empty",               BindingFlags.Public | BindingFlags.Static).GetValue(null);   Console.WriteLine(s); 

And you'll see "Pink". My guess is that it is intercepted by the jitter. I can't give hard evidence for that however. There's precedent, try tinkering with Decimal.MaxValue for example, another readonly static value. Not changeable in 3.5 either, the jitter recognizes it and generates the value directly without reading the field.

I just found out you put a bounty on another question with the exact same subject. 280Z28's post is pretty similar.

like image 188
Hans Passant Avatar answered Oct 02 '22 20:10

Hans Passant