Differencebetween a Mutable and Immutable String in C#

What is the difference between mutable and immutable?

Immutable means that once initialized, the state of an object cannot change.

Mutable means it can.

For example - strings in .NET are immutable. Whenever you do an operation on a string (trims, upper casing, etc...) a new string gets created.

In practice, if you want to create an immutable type, you only allow getters on it and do not allow any state changes (so any private field cannot change once the constructor finished running).

Immutable vs Mutable C#

Yup, that looks reasonable.

However, I would also talk about "leaky" mutability. For example:

public class AppearsImmutableButIsntDeeplyImmutable
{
private readonly StringBuilder builder = new StringBuilder();
public StringBuilder Builder { get { return builder; } }
}

I can't change which builder an instance appears on, but I can do:

value.Builder.Append("hello");

It would be worth you reading Eric Lippert's blog post on kinds of immutability - and indeed all the rest of the posts in the series.

What is difference between mutable and immutable String in java

Case 1:

String str = "Good";
str = str + " Morning";

In the above code you create 3 String Objects.

  1. "Good" it goes into the String Pool.
  2. " Morning" it goes into the String Pool as well.
  3. "Good Morning" created by concatenating "Good" and " Morning". This guy goes on the Heap.

Note: Strings are always immutable. There is no, such thing as a mutable String. str is just a reference which eventually points to "Good Morning". You are actually, not working on 1 object. you have 3 distinct String Objects.


Case 2:

StringBuffer str = new StringBuffer("Good"); 
str.append(" Morning");

StringBuffer contains an array of characters. It is not same as a String.
The above code adds characters to the existing array. Effectively, StringBuffer is mutable, its String representation isn't.

What's the practical difference between a variable being mutable vs non-mutable

I understand that the run-time(or compiler, or whatever) is actually getting rid of the reference to the original string greeting and replacing it with a new concatenated one of the same name.

Pedantic intro: No. Objects do not have names -- variables do. It is storing a new object in the same variable. Thus, the name (variable) used to access the object is the same, even though it (the variable) now refers to another object. An object may also be stored in multiple variables and have multiple "names" at the same time or it might not be accessible directly by any variable.

The other parts of the question have already been succinctly answered for the case of strings -- however, the mutable/immutable ramifications are much larger. Here are some questions which may widen the scope of the issue in context.

  1. What happens if you set a property of an object passed into a method? (There are these pesky "value-types" in C#, so it depends...)
  2. What happens if a sequence of actions leaves an object in an inconsistent state? (E.g. property A was set and an error occurred before property B was set?)
  3. What happens if multiple parts of code expect to be modifying the same object, but are not because the object was cloned/duplicated somewhere?
  4. What happens if multiple parts of code do not expect the object to be modified elsewhere, but it is? (This applies in both threading and non-threading situations)

In general, the contract of an object (API and usage patterns/scope/limitations) must be known and correctly adhered to in order to ensure program validity. I generally find that immutable objects make life easier (as then only one of the above "issues" -- a meager 25% -- even applies).

Happy coding.

string is immutable and stringbuilder is mutable

You cannot edit the value of a string, each method of the string object returns a new string instead of altering the original. StringBuilder on the other hand can alter it's content (adding new strings for example).

string original = "the brown fox jumped over the lazy dog";
string altered = original.Insert(original.IndexOf("fox"), "cat");
// altered = the brown cat jumped over the lazy dog

You cannot change the content of the original string unless you create a new string, or re-reference the instance to another string object.

What is the difference bewteen the string and string builder in c#

StringBuilder is mutable which gives better performance when you need to manipulate content multiple times.

In case of string, it has to create instances multiple times because string is immutable.

Why .NET String is immutable?

  1. Instances of immutable types are inherently thread-safe, since no thread can modify it, the risk of a thread modifying it in a way that interferes with another is removed (the reference itself is a different matter).
  2. Similarly, the fact that aliasing can't produce changes (if x and y both refer to the same object a change to x entails a change to y) allows for considerable compiler optimisations.
  3. Memory-saving optimisations are also possible. Interning and atomising being the most obvious examples, though we can do other versions of the same principle. I once produced a memory saving of about half a GB by comparing immutable objects and replacing references to duplicates so that they all pointed to the same instance (time-consuming, but a minute's extra start-up to save a massive amount of memory was a performance win in the case in question). With mutable objects that can't be done.
  4. No side-effects can come from passing an immutable type as a method to a parameter unless it is out or ref (since that changes the reference, not the object). A programmer therefore knows that if string x = "abc" at the start of a method, and that doesn't change in the body of the method, then x == "abc" at the end of the method.
  5. Conceptually, the semantics are more like value types; in particular equality is based on state rather than identity. This means that "abc" == "ab" + "c". While this doesn't require immutability, the fact that a reference to such a string will always equal "abc" throughout its lifetime (which does require immutability) makes uses as keys where maintaining equality to previous values is vital, much easier to ensure correctness of (strings are indeed commonly used as keys).
  6. Conceptually, it can make more sense to be immutable. If we add a month onto Christmas, we haven't changed Christmas, we have produced a new date in late January. It makes sense therefore that Christmas.AddMonths(1) produces a new DateTime rather than changing a mutable one. (Another example, if I as a mutable object change my name, what has changed is which name I am using, "Jon" remains immutable and other Jons will be unaffected.
  7. Copying is fast and simple, to create a clone just return this. Since the copy can't be changed anyway, pretending something is its own copy is safe.
  8. [Edit, I'd forgotten this one]. Internal state can be safely shared between objects. For example, if you were implementing list which was backed by an array, a start index and a count, then the most expensive part of creating a sub-range would be copying the objects. However, if it was immutable then the sub-range object could reference the same array, with only the start index and count having to change, with a very considerable change to construction time.

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 modeled 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.

Immutable Strings

Firstly, strings are immutable and that's that.

var string1 = "string";
var string2 = string1;
string2 = "string2";

Console.WriteLine(string1);
Console.WriteLine(string2);

Output


string
string2

Secondly, why do you really want an mutable string? Here are many reasons why strings "are" immutable. see Why .NET String is immutable?

Lastly, if you really want an immutable string you can create an instance of StringBuilder You get mutability, however it will reallocate its internal buffer every-time it needs to, or you can roll your own fancy pants class.

string.Concat, Mutable or Immutable?

Both options are almost identical. This is how string.Concat(IEnumerable<string>) is implemented:

[ComVisible(false)]
public static String Concat(IEnumerable<String> values) {
if (values == null)
throw new ArgumentNullException("values");
Contract.Ensures(Contract.Result<String>() != null);
Contract.EndContractBlock();

StringBuilder result = StringBuilderCache.Acquire();
using(IEnumerator<String> en = values.GetEnumerator()) {
while (en.MoveNext()) {
if (en.Current != null) {
result.Append(en.Current);
}
}
}
return StringBuilderCache.GetStringAndRelease(result);
}

I would go with string.Concat, because why write a method that already exists.



Related Topics



Leave a reply



Submit