As we all know, String is immutable. What are the reasons for String being immutable and the introduction of StringBuilder class as mutable?
|
In all, for objects which don't have undergoing change as part of their purpose, there can be many advantages in being immutable. The main disadvantage is in requiring extra constructions, though even here it's often overstated (remember, you have to do several appends before StringBuilder becomes more efficient than the equivalent series of concatenations, with their inherent construction). It would be a disadvantage if mutability was part of the purpose of an object (who'd want to be modelled by an Employee object whose salary could never ever change) though sometimes even then it can be useful (in a many web and other stateless applications, code doing read operations is separate from that doing updates, and using different objects may be natural - I wouldn't make an object immutable and then force that pattern, but if I already had that pattern I might make my "read" objects immutable for the performance and correctness-guarantee gain). Copy-on-write is a middle ground. Here the "real" class holds a reference to a "state" class. State classes are shared on copy operations, but if you change the state, a new copy of the state class is created. This is more often used with C++ than C#, which is why it's std:string enjoys some, but not all, of the advantages of immutable types, while remaining mutable. |
|||||||
|
Making strings immutable has many advantages. It provides automatic thread safety, and makes strings behave like an intrinsic type in a simple, effective manner. It also allows for extra efficiencies at runtime (such as allowing effective string interning to reduce resource usage), and has huge security advantages, since it's impossible for an third party API call to change your strings. StringBuilder was added in order to address the one major disadvantage of immutable strings - runtime construction of immutable types causes a lot of GC pressure and is inherently slow. By making an explicit, mutable class to handle this, this issue is addressed without adding unneeded complication to the string class. |
|||||||||||||||
|
string management is an expensive process. keeping strings immutable allows repeated strings to be reused, rather than re-created. |
|||||||||||||
|
Why are string types immutable in C#
|
|||
|
You never have to defensively copy immutable data. Despite the fact that you need to copy it to mutate it, often the ability to freely alias and never have to worry about unintended consequences of this aliasing can lead to better performance because of the lack of defensive copying. |
|||
|
Strings and other concrete objects are typically expressed as immutable objects to improve readability and runtime efficiency. Security is another, a process can't change your string and inject code into the string |
|||
|
Imagine you pass a mutable string to a function but don't expect it to be changed. Then what if the function changes that string? In C++, for instance, you could simply do call-by-value (difference between This is just one of various reasons. Performance is another one (interned strings, for example). |
|||
|
Strings are passed as reference types in .NET. Reference types place a pointer on the stack, to the actual instance that resides on the managed heap. This is different to Value types, who hold their entire instance on the stack. When a value type is passed as a parameter, the runtime creates a copy of the value on the stack and passes that value into a method. This is why integers must be passed with a 'ref' keyword to return an updated value. When a reference type is passed, the runtime creates a copy of the pointer on the stack. That copied pointer still points to the original instance of the reference type. The string type has an overloaded = operator which creates a copy of itself, instead of a copy of the pointer - making it behave more like a value type. However, if only the pointer was copied, a second string operation could accidently overwrite the value of a private member of another class causing some pretty nasty results. As other posts have mentioned, the StringBuilder class allows for the creation of strings without the GC overhead. |
|||||
|
Strings are not really immutable. They are just publicly immutable. It means you cannot modify them from their public interface. But in the inside the are actually mutable. If you don't believe me look at the String.Concat definition using reflector. The last lines are...
As you can see the Actually the Maybe there are better examples but this is the one I have found so far. |
|||
|
Just to throw this in, an often forgotten view is of security, picture this scenario if strings were mutable:
You see how it could be very, very bad if you were allowed to mutate strings once they were passed. |
|||||||
|
Imagine being an OS working with a string that some other thread was modifying behind your back. How could you validate anything without making a copy? |
|||||
|
There are five common ways by which a class data store data that cannot be modified outside the storing class' control:
Because strings are of variable length, they cannot be value-type primitives, nor can their character data be stored in a struct. Among the remaining choices, the only one which wouldn't require that strings' character data be stored in some kind of immutable object would be #5. While it would be possible to design a framework around option #5, that choice would require that any code which wanted a copy of a string that couldn't be changed outside its control would have to make a private copy for itself. While it hardly be impossible to do that, the amount of extra code required to do that, and the amount of extra run-time processing necessary to make defensive copies of everything, would far outweigh the slight benefits that could come from having |
|||
|