In this article, we’re going to tackle the popular question among many developers, and that’s “What’s the difference between string and String” and “When should I use string, and when should I use String” in my applications.

Both of these versions exist for a reason, so let’s see what they are and if they’re indeed that important.

This article is divided into the following sections:

Let’s dive in.

What Is String, and What Is String?

String or rather System.String is a class and it’s used to represent a sequence of UTF-16 code units or rather System.Char.Simply put it represents text. It’s a class like any other and it inherits from System.Object. It’s also a .NET (Framework or Core) type and its immutable by its nature which means it cannot be changed after it’s created. If you change it, you practically create and return another string upon modification of the existing string. That’s where StringBuilder comes in.

On the other hand, string is a C# reserved keyword and an alias for String. That means you can do something like this:

And this will be okay with the compiler, no problems whatsoever. It’s a nice feature and most of the time we don’t think too much about which one we use.

That brings us to the next point.

Are They the Same Thing?

But are they really the same thing though?

The answer is yes and no. What do we mean by that?

While they are the same and they compile the same way to the IL (Intermediate Language):

There are some differences to think about when using them. String can be anything because it’s not a reserved keyword. It can be used as a variable name for example. It’s not forbidden, but we’ll see what the cost of that can be. string on the other hand, cannot be used like that.

Other Aliases in C#

Beside string, there are several other aliases in C#:

  • object:  System.Object
  • bool:    System.Boolean
  • byte:    System.Byte
  • sbyte:   System.SByte
  • short:   System.Int16
  • ushort:  System.UInt16
  • int:     System.Int32
  • uint:    System.UInt32
  • long:    System.Int64
  • ulong:   System.UInt64
  • float:   System.Single
  • double:  System.Double
  • decimal: System.Decimal
  • char: System.Char

Mind you that not all of these are classes. Most of the types are structs and point to value types, with the exception of System.Objectand System.String.

What Are the Differences Between String and String in Practice?

To understand the differences even better, let’s go through some examples.

Example 1: variable names

String can be used as a variable name, string cannot.

There is one exception to this rule and that’s by using a special character @ (verbatim identifier) as a prefix to indicate that the keyword can be used as an identifier:

As for the reason why you would do this ever, we have no idea. If you do, let us know in the comments section.

Example 2: nameof and typeof

Aliases, including string, can’t be used as a parameter for the nameof expression, because they are not types themselves.

The typeof operator, on the other hand, is okay with either:

In both cases, the result is the same and that’s System.String.

Example 3: underlying enum types

You might find this one while Google-ing, but it’s actually not true. It’s said that the underlying enum type must be declared as an alias:

This is not true, it both compiles, and the enum types are called as usual.

Example 4: context matters

Take a look at this example:

What would you say the result of this code is? If you guessed syntax error in both cases, you were right.

But, that’s not the whole story.

If we add something like this:

It makes the syntax error on the second line disappear.

Why?

Because the compiler now treats the String type as an Int32 type. This just goes to show that string and String are not entirely the same.

Example 5: aliases as generic types

We can’t use a keyword as a generic type parameter, but we can name it String though:

This is certainly not recommended, but it’s another example of how different these are.

Example 6: String as a class name

String can be a class name:

There are some serious consequences of using it like that though. Both lines in the Example method are going to report a syntax error because now, String is just a class inside the MyClass. It’s not String anymore.

Example 7: String as an identifier

Same goes for using String as a variable name:

This inevitably results in a syntax error.

Enough examples? Let’s get to the important point.

Which One Should I Use?

There is a general consensus that string should be used when defining variable types, and that String should be used to call the String class methods and fields:

We would go a bit further than that to say that if you work in a corporate environment, or in a team of developers, you should choose consistency over this style. Sometimes it’s more important to be consistent than to follow the unwritten rules that someone else has come up with.

But, Is It Just the Matter Style Though?

We’ve come to the most important part. Is this just a question of code style?

We’ve gone through some of the examples (Examples 4, 5, 6, 7) where we’ve seen that using String in certain scenarios can lead to potential problems, and there are some things that simply cannot be done with a keyword itself.

In terms of safety, it’s safer to use string over String, since compiler helps us avoid almost all problematic scenarios.

On the other hand, String is used in many valid scenarios like reflection, lexers, serialization, protocols… And for such libraries, string vs String might be an important issue.

We hope this clears it up a bit.

Conclusion

In this guide, we’ve reviewed the differences between String and string, and we’ve shown a few examples to demonstrate these differences.

If you have some interesting examples of string vs String yourself, we would like to hear from you in the comments section.