.Net/C# objects are immutable! Repeat after me, it's a lie!

Being a Contract Developer, or Freelancer should you prefer, you find yourself constantly going to interviews, proffering your skills, and undergoing an obligatory technical interview quiz.

In the C# component of the interview, the same questions come up over and over, viz. Net Garbage Collection (GC) behaviour and heaps and stacks, value and reference types and boxing, object immutability, design patterns, and the differences between interfaces, classes, and abstract classes.

On each occasion, I am never sure on how to respond to these questions. Do I risk an Aunt Sally, or do I respond with the rote expected answer, and then and only then respond further should the interviewer probe further (and either way this is a game to be played with the upmost of caution because of the potential repercussions; I don’t go to interviews for fun, I go to win new work, and no work means no food).

All five topics listed above have rote answers, discussed ad nauseam on various online forums, and almost all the example answers you can find are incorrect yet repeated over and over. For example:

Question: are Strings immutable in .Net?

Are they? Really? Of course they are, and the general software developer behaviour to confirm this fact is to launch a web browser and search using a few judiciously chosen keywords; general purpose search engines are after all the main means by which you ascertain facts nowadays (if this sentence sounds a little patronising, my  lack of subtlety has not been lost on you). This quick online search confirms the typical result-set obtained. A cursory browse of the top few hits in this ad hoc search prove inconclusively that C#/.Net Strings are immutable. Therefore they are.  To paraphrase myself – someone else wrote Strings are immutable, the answer has been voted up and perhaps endorsed by loads of other people you’ve never heard of, the hit appears at or near the top of my search engine result set, and therefore Strings are immutable. Even the official Microsoft documentation states that strings are immutable. Full stop – this really is a non-starter.

So,

Question: are Strings immutable in .Net? (that is the same question, a second time, just in case you have missed it).
Answer: No, of course they are not, and you can only imagine the dogmatic offerings from the various participants during the interview after making that type of unsubstantiated response. Can “the quick brown fox jumps over the lazy dog” be modified to “THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG”  without creating a new String instance by, for example:


   String s = "the quick brown fox jumps over the lazy dog";
   s = s.ToUpper();

Yes, in this unimaginative example, this String is immutable, and yes, conversion to upper case has created a new String instance, referenced by the same name (s), and yes the the old one in lower case will be GC’d at some point.

But … and backing up the initial and contentious throw-away comment with a bit of trivial C# code contrived to demonstrate my point during interview (and more fully in this blog):


   using System;

   namespace ConsoleApplication6
   {
     class Program
     {
       static void Main(string[] args)
       {
         String s = "the quick brown fox jumps over the lazy dog";
         unsafe
         {
           fixed (char* ca = s)
           {
              for (char* c = ca; *c != 0; c++)
              *c = char.ToUpper(*c);
           }
         }
         Console.WriteLine(s);
       }
     }
   }

NetStringsImmutableArentThey

the same question can be asked again, and now for a third time – this really is getting boring but I am seriously trying to drive my point home.

Question: are Strings immutable in .Net? [in other words can the String s that has value ‘the quick brown fox jumps over the lazy dog‘ be modified (to upper case) after it is created without creating a new String instance. The answer is, perhaps surprisingly for you, yes it can!].

With a sprinkling of code and partial screenshot, I have made my point, and if you understand the code, I have made it well. I think too that I have provided ample opportunity to steer the interview away from the rote and quite boring Q&A toward a proper discussion. Note specifically too that I have not given a smart alec answer using .Net unsafe code, open to much discussion, without applicability to real-life applications. Real-life applications that require authentication with passwords, for example, transported around in an API as String’s (for some reason), will  (well should) use this type of code to zap the string content (the password) after it has been used. To answer a question with a question: if you are passing a password around your application as a String, should you leave it in memory to be garbage collected at some point, available for all to see and abuse, perhaps even to remain in RAM and visible after the application has terminated? The answer is “Of course not”, followed by many exclamation marks. If you really need to pass the password around as a String you should cleanup at some point or, to put it another way, the immutable string should be modified/overwritten so it isn’t available to other processes, or hackers, through an uncontrolled and insecure mechanism.

— Published by Mike, 13:43:32 07 August 2016

Leave a Reply