C# String in Depth

C# String in Depth with Examples

In this article, I am going to discuss C# String in Depth with examples. Please read our previous article, where we discussed C# Data Types in detail. As a developer, it is very important to understand the concept of C# strings and I am also sure you are using the C# string in all of your projects. But there are many things that you should know from a performance point of view. So, as part of this article, we are going to discuss the following pointers in detail with examples.

  1. Strings are reference types
  2. Understanding the difference between string(small) vs String(Capital).
  3. Why strings are immutable?
  4. How we can improve performance using String intern?
  5. StringBuilder for concatenation.
  6. Why they made string is immutable.
Strings are reference types in C#:

C# strings are objects i.e. they are not normal data types. For example, if we define some variables using int or double data types as shown below,

Primitive Types are Struct in C#

Then if you right-click on the data type and go to the definition then you will see that they are struct as shown in the below image. Struct means they are value type.

Struct in C#

On the other hand, if you define a variable with string data type as shown below.

string in C#

Then if you right-click on the string data type and click on go to definition then you will see that it is a class. Class means reference data type.

Strings are reference type in C#

So, the first point that you need to remember is strings are reference types while other primitive data types are struct types.

String(Capital) vs string(small) in C#:

You can use the string in two ways. I.e. you can use the string using capital S or by using the small “s” as shown in the below image.

String(Capital) vs string(small) in C#

Now the question that should come to your mind is what is the difference between these two (string vs String). Let’s understand this. The small string is actually an alias of String (Capital string). If you right-click on the small string and if you go to the definition then you will see that the actual class name is capital string i.e. String as shown in the below image.

what is the difference between string and String in C#

You can use any one of them i.e. either string or String. But as per the naming convention when you are creating a variable use the small string but whenever you want to invoke methods on the string then use the capital string as shown in the below image.

The small string is actually an alias of Capital String

Strings are immutable in C#:

Before understanding strings are immutable, first, we need to understand two terms i.e. Mutable and Immutable. Mutable means can be changed whereas Immutable means can not be changed. C# strings are immutable means C# strings cannot be changed. Let us understand this with an example.

Please have a look at the below image. When the first statement executed, it will create one object and assign the value DotNet. But when the second statement executed, it will not override the first object, it lets the first object be there for garbage collection and creates a fresh object, and assign the value Tutorials.

Strings are immutable in C#

So, when the above two statements executed, internally two memory locations are created. One with the value DotNet and the current one with the value Tutorials and the current one is going to be referred in the program. So, each time, you assign a new value to the string variable, a new object is created and this is the reason why strings are immutable.

But this is not the case with a value type. For example, please have a look at the below two statements. When the first statement is executed one memory location is created and assign the value 100 and when the second statement executed it will not create a new memory location rather it will override the value of the same memory location.

Proves C# strings are immutable

Example to proves C# strings are immutable:

Let us see an example to understand this. Please copy and paste the following code. As you can see here we have a heavy for loop. As part of the Loop, we assigning a value to the string str variable. Here, we are using GUID to generate a new value, and each time it will create a new value and assign it to the str variable. Again, we are using Stopwatch to check how much time it took to execute the loop.

using System;
using System.Diagnostics;

namespace StringDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            string str = "";
            Console.WriteLine("Loop Started");
            var stopwatch = new Stopwatch();

            stopwatch.Start();
            for (int i = 0; i < 30000000; i++)
            {
                 str = Guid.NewGuid().ToString();
            }
            stopwatch.Stop();

            Console.WriteLine("Loop Ended");
            Console.WriteLine("Loop Exceution Time in MS :" + stopwatch.ElapsedMilliseconds);

            Console.ReadKey();
        }
    }
}

Output: When you execute the program, you will get the following output. The time may vary in your machine.

Proves C# strings are immutable

As you can see in the above output, it approximately took 26000 milliseconds to execute the loop. Each time the loop executes, it creates a fresh string object and assigns the new value to it. This is because strings are immutable.

Example using integer:

In the following example, instead of a string, we are using an integer variable. As integers are not immutable, so it will not create a fresh memory location each time the loop executes instead it will use the same memory location and update its value.

using System;
using System.Diagnostics;

namespace StringDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            int ctr =0;
            Console.WriteLine("Loop Started");
            var stopwatch = new Stopwatch();

            stopwatch.Start();
            for (int i = 0; i < 30000000; i++)
            {
                ctr = ctr + 1;
            }
            stopwatch.Stop();

            Console.WriteLine("Loop Ended");
            Console.WriteLine("Loop Exceution Time in MS :" + stopwatch.ElapsedMilliseconds);

            Console.ReadKey();
        }
    }
}
Output:

Example using integer

As you can see in the above output, it only took 84 milliseconds to execute the loop.

Example: String with Same value

As you can see in the below example, which is exactly the same as the first example, but here instead of using GUID, we are assigning a fixed value to the string str variable.

using System;
using System.Diagnostics;

namespace StringDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            string str = "";
            Console.WriteLine("Loop Started");
            var stopwatch = new Stopwatch();

            stopwatch.Start();
            for (int i = 0; i < 30000000; i++)
            {
                str ="DotNet Tutorials";
            }
            stopwatch.Stop();

            Console.WriteLine("Loop Ended");
            Console.WriteLine("Loop Exceution Time in MS :" + stopwatch.ElapsedMilliseconds);

            Console.ReadKey();
        }
    }
}
Output:

String Interning in C#

As you can see in the above output it only took 95 milliseconds. This is because in this case fresh objects are not created each time the loop executes. Now, the question that should come to your mind is why? The answer is String intern. So, let us understand string interning in detail.

String Interning in C#:

The String Interning in C# is a process that uses the same memory location if the value is the same. In our example, when the loop executes for the first time, it will create a fresh object and assign the value “DotNet Tutorials” to it. When the loop executes 2nd time, before creating a fresh object, it will check whether this “DotNet Tutorials” value is already there in the memory, if yes then it simply uses that memory location else it will create a new memory location. This is nothing but C# string interning.

So, if you are running a for loop and assigning the same value again and again, then it uses string interning to improve the performance. In this case, rather than creating a new object, it uses the same memory location.

StringBuilder for concatenation:

The C# string immutability behavior can be very very dangerous when it comes to string concatenation. Let us understand this with an example. In the below example, we are concatenating the string using the for loop.

using System;
using System.Diagnostics;

namespace StringDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            string str = "";
            Console.WriteLine("Loop Started");
            var stopwatch = new Stopwatch();

            stopwatch.Start();
            for (int i = 0; i < 30000; i++)
            {
                str ="DotNet Tutorials" + str;
            }
            stopwatch.Stop();

            Console.WriteLine("Loop Ended");
            Console.WriteLine("Loop Exceution Time in MS :" + stopwatch.ElapsedMilliseconds);

            Console.ReadKey();
        }
    }
}
Output:

concatenation using string

As you can see in the above image, it took 5473 milliseconds to execute the loop. In order to understand how it executes the loop, please have a look at the below image. The loop executes the first time, it will create a new memory location and store the value “DotNet Tutorials”. For the second time, it creates another fresh memory location (fresh object) and stores the value “DotNet Tutorials DotNet Tutorials” and the first memory location will be going for garbage collection. And the same process will continue i.e. each time the loop executes a new memory location will be created and previous ones will be going for garbage collection.

concatenation flow using C# string

In order to solve the above string concatenation problem, the .NET Framework provides the StringBuilder class. As the name itself saying everything, the string builder class is used to build a string. If you use string builder then fresh objects are not going to be created.

Example using StringBuilder:

In the following example, we are using the StringBuilder class to concatenate strings. Here, first, we create an instance of the StringBuilder class and then use the Append method to concatenate the string.

using System;
using System.Diagnostics;
using System.Text;

namespace StringDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            StringBuilder stringBuilder = new StringBuilder();
            Console.WriteLine("Loop Started");
            var stopwatch = new Stopwatch();

            stopwatch.Start();
            for (int i = 0; i < 30000; i++)
            {
                stringBuilder.Append("DotNet Tutorials");
            }
            stopwatch.Stop();

            Console.WriteLine("Loop Ended");
            Console.WriteLine("Loop Exceution Time in MS :" + stopwatch.ElapsedMilliseconds);

            Console.ReadKey();
        }
    }
}
Output:

concatenation using string builder

As you can see in the above output, it only took 1 millisecond to concatenate the string comparing to 5473 using string. This is because every time the for loop runs it will not create fresh objects rather than it will use the same memory location.

Why they made C# String Immutable?

They made Strings as Immutable for Thread Safety. Think of one situation where you have many threads and all the threads want to manipulate the same string object as shown in the below image. If strings are mutable then we have thread-safety issues.

Why they made C# String as Immutable?

In case if you are new to thread safety, I strongly recommended you to read the following article, where we discussed Thread and Thread Safety in detail.

https://dotnettutorials.net/lesson/multithreading-in-csharp/

In the next article, I am going to discuss Static in C# with examples. Here, in this article, I try to explain Strings in C# with examples and I hope you enjoy this Strings in C# with examples article. I would like to have your feedback. Please post your feedback, question, or comments about Strings in C# with examples article.

Leave a Reply

Your email address will not be published. Required fields are marked *