In this article, we’re going to take a look at how to make the first letter of a string upper case in C#. We’ll see some different approaches and investigate their performance characteristics. By the end of this article, we should have a good understanding of which approach is best for our needs.
Without further ado, let’s get started!
Substring Technique
To successfully convert the first letter of a string to upper case, we have to extract the first letter of the string and use the inbuilt ToUpper()
method to convert the first character to upper case.
Let’s implement a method to illustrate this concept:
public string FirstCharSubstring(string input) { if (string.IsNullOrEmpty(input)) { return string.Empty; } return $"{input[0].ToString().ToUpper()}{input.Substring(1)}"; }
First, we check whether the string is null or empty before extracting the first character from the string and invoking the ToUpper()
method to convert the first letter to upper case. Then, we concatenate the first character with the rest of the substring, which we return back to the user.Â
For all the unit tests we are going to implement today, we are going to use the same class object:
FirstLetterToUpperMethods upperCase = new FirstLetterToUpperMethods();
Next, we can verify that the method successfully achieves its purpose by checking whether char.IsUpper()
returns true
.
var testString = "this is a test string"; var returnedString = upperCase.FirstCharSubstring(testString); Assert.IsTrue(char.IsUpper(returnedString[0]));
Use the AsSpan() Method
We can use the inbuilt AsSpan()
method to convert the first letter of a string to upper case. The AsSpan()
method creates a new read-only span over a string starting from the second character to the last one, which avoids more memory allocation and improves its performance:
public string FirstCharToUpperAsSpan(string input) { if (string.IsNullOrEmpty(input)) { return string.Empty; } Span<char> destination = stackalloc char[1]; input.AsSpan(0, 1).ToUpperInvariant(destination); return $"{destination}{input.AsSpan(1)}"; }
The FirstCharToUpperAsSpan()
method takes a string and checks whether it is null or empty and returns an empty string if true
.
Otherwise, we use stackalloc
to create a block of memory on the stack for one character. Next, we make the first letter of the string upper case by invoking the AsSpan()
method together with the ToUpperInvariant()
method.
Finally, we create a read-only span over the rest of the substring and concatenate it with the first letter of the string by invoking the AsSpan()
method and return it back to the user.Â
Let’s verify that the method achieves its purpose with the test:
var testString = "this is a test string"; var returnedString = upperCase.FirstCharToUpperAsSpan(testString); Assert.IsTrue(char.IsUpper(returnedString[0]));
Update: Using string.Create With AsSpan
If you want to improve the Span implementation and gain even more performance you can use string.Create
method:
public string FirstCharToUpperStringCreate(string input) { if (string.IsNullOrEmpty(input)) { return string.Empty; } return string.Create(input.Length, input, static (Span<char> chars, string str) => { chars[0] = char.ToUpperInvariant(str[0]); str.AsSpan(1).CopyTo(chars[1..]); }); }
You can check our source code and run the prepared benchmark to see even better performance with this implementation. We would like to thank our reader Joel for adding this suggestion in the comment section.
Make Use of Char.ToUpper() Method
This method works in the same way as the string.ToUpper() technique, as we can invoke the char.ToUpper()
method to convert the first letter of the string into the upper case:
public string FirstCharToUpper(string input) { if (string.IsNullOrEmpty(input)) { return string.Empty; } return $"{char.ToUpper(input[0])}{input[1..]}"; }
The FirstCharToUpper()
method takes the first character input[0]
and invokes the char.ToUpper()
method to convert it to upper case. We complete the process by concatenating it with the rest of the array of characters and returning it as a string.Â
We can proceed to check that our implementation converts the first character to upper case:
var testString = "this is a test string"; var returnedString = upperCase.FirstCharToUpper(testString); Assert.IsTrue(char.IsUpper(returnedString[0]));
Utilize Character Arrays
Since we can view a string as an array of characters, we can convert the string into an array and invoke the char.ToUpper()
method to convert the first letter of the array to upper case before returning it as a string:
public string FirstCharToCharArray(string input) { if (string.IsNullOrEmpty(input)) { return string.Empty; } var stringArray = input.ToCharArray(); if (char.IsLower(stringArray[0])) { stringArray[0] = char.ToUpper(stringArray[0]); } return new string(stringArray); }
After checking whether input
is null or empty, we convert it into an array of characters by invoking the string.ToCharArray()
method. Next, we convert the first element in the array to upper case by invoking the char.ToUpper()
method, after checking if it is in lower case by invoking the char.IsLower()
method. We return a new string object after converting the first letter of the string to upper case.Â
We can verify that the method converts the first letter of a string to upper case:
var testString = "this is a test string"; var returnedString = upperCase.FirstCharToCharArray(testString); Assert.IsTrue(char.IsUpper(returnedString[0]));
Regular Expressions
C# supports regular expressions, which we can find in the System.Text.RegularExpressions
namespace. We can use the Regex.Replace()
method to convert the first letter of a string to upper case:
public string FirstCharToUpperRegex(string input) { if (string.IsNullOrEmpty(input)) { return string.Empty; } return Regex.Replace(input, "^[a-z]", c => c.Value.ToUpper()); }
In this case, input
is the string we are checking for lowercase characters. "^[a-z]"
is the regular expression pattern we are using to match the first character of our input
string. When the Regex.Replace()
method encounters a lowercase character at the start of a string, based on our pattern, it replaces it with its uppercase equivalent by invoking the ToUpper()
method in the last section c => c.Value.ToUpper()
.
We can verify that our solution converts the first letter of a string to upper case with a test:
var testString = "this is a test string"; var returnedString = upperCase.FirstCharToUpperRegex(testString); Assert.IsTrue(char.IsUpper(returnedString[0]));
Convert the First Letter to Upper Case Through LINQ
Another way we can convert the first letter of a string to uppercase is to use LINQ. To make our example simple, we are going to use the FirstOrDefault()
method to extract the first character from the input string and invoke the ToUpper()
method to convert it to upper case:
public string FirstCharToUpperLinq(string input) { if (string.IsNullOrEmpty(input)) { return string.Empty; } return $"{input.FirstOrDefault().ToString().ToUpper()}{input.Substring(1)}"; }
We extract the first letter of the string, convert it to upper case, and concatenate it with the rest of the substring before returning it to the user.
Now let’s test this logic:
var testString = "this is a test string"; var returnedString = upperCase.FirstCharToUpperLinq(testString); Assert.IsTrue(char.IsUpper(returnedString[0]));
Unsafe Code
Besides using LINQ, we can use unsafe code to convert the first letter of a string to uppercase. Unsafe code is code that bypasses the type safety features of the CLR (Common Language Runtime). This makes it possible to write more efficient code, but it also comes with the risk of introducing bugs and security vulnerabilities.Â
Without further ado, let’s implement a function that uses unsafe code to convert the first letter of a string to upper case:
public string FirstCharToUpperUnsafeCode(string input) { if (string.IsNullOrEmpty(input)) { return string.Empty; } unsafe { fixed (char* p = input) { *p = char.ToUpper(*p); } } return input; }
We use the fixed
keyword to pin the input
string in memory, which prevents it from being moved by the GC (Garbage Collector). Next, a pointer allows us to directly access the first character of the string and convert it to upper case by invoking the char.ToUpper()
method.
This is the most efficient way to convert the first letter of a string to uppercase, as it doesn’t allocate a new string instance or copy all characters from the original string. However, as mentioned before, it comes with the risk of introducing bugs and security vulnerabilities. Therefore, it should only be used if absolutely necessary.
Performance Tests
Let’s assess how these techniques perform by running performance benchmarks. First, we are going to implement a method that generates a random string, which we are going to pass to our examples:
private string GenerateRandomString(int size) { var random = new Random(); var charOptions = "abcdefghijklmnopqrstuvwxyz"; return new string(Enumerable.Repeat(charOptions, size).Select(s => s[random.Next(s.Length)]).ToArray()).ToLower(); }
First, we define a string charOptions
that contains all the alphabet characters, which we will use to generate random strings. Then, we use the inbuilt random class, LINQ, and the length
of the string to return a new random string.Â
Next, we are going to create a new object that passes random strings each having a length of 2000 to our examples:
public IEnumerable<object[]> SampleStrings() { yield return new object[] { GenerateRandomString(2000)}; }
Let’s assess how the different ways of making the first letter of a string to upper case perform:
| Method | Mean | Error | StdDev | Median | Rank | Gen0 | Allocated | |--------------------------- |------------:|----------:|-----------:|------------:|-----:|-------:|----------:| | FirstCharToUpperUnsafeCode | 11.42 ns | 0.559 ns | 1.629 ns | 10.72 ns | 1 | - | - | | FirstCharToUpperAsSpan | 503.27 ns | 5.577 ns | 7.445 ns | 501.63 ns | 2 | 1.9455 | 4072 B | | FirstCharToCharArray | 708.50 ns | 28.916 ns | 83.431 ns | 674.44 ns | 3 | 3.8452 | 8048 B | | FirstCharSubstring | 776.43 ns | 26.798 ns | 77.746 ns | 752.26 ns | 4 | 3.8681 | 8096 B | | FirstCharToUpperRegex | 812.18 ns | 63.639 ns | 183.614 ns | 722.32 ns | 4 | 2.0447 | 4280 B | | FirstCharToUpperLinq | 821.74 ns | 32.291 ns | 93.168 ns | 800.28 ns | 5 | 3.8834 | 8128 B | | FirstCharToUpper | 1,630.43 ns | 67.976 ns | 200.429 ns | 1,624.30 ns | 6 | 3.8452 | 8048 B |
The results show that using the unsafe code technique seems to be the fastest (11.42 ns), and the Char.ToUpper() technique is the slowest (830.28 ns). The AsSpan()
 technique performs marginally better than the rest of the other methods that utilize the Substring()
methods, as the latter, allocate a new string object on the heap and create a copy of the substrings, which affects their performance, which we can see from the memory size computations in the “Allocated” column.
Conclusion
In this article, we learned the different techniques that we can use to convert the first letter of a string to upper case.Â
To clarify the “comes with the risk of introducing bugs”: one bug I see is with interned strings. If an interned string get capitalized it will not only capitalize the input, but also other strings which have the same interned string.
This could be alleviated by checking with “string.IsInterned” and if it is an interned string it should fallback to one of the other methods. Though this will probably give a false sense of security as there are other bug sources around the proper usage of FirstCharToUpperUnsafeCode arising from the fact that strings are meant to be immutable and are treated as such by the CLR and probably the JITter.
Thanks a lot, Mike for this explanation. This is great to have here.
I suspect that string.Create() might beat out the other approaches, except for the unsafe version:
return string.Create(input.Length, input, static (Span<char> chars, string str) =>
{
chars[0] = char.ToUpperInvariant(str[0]);
str.AsSpan(1).CopyTo(chars[1..]);
});
Indeed, on my machine the string.Create() approach comes in second at 263.9 ns. Third is FirstCharToUpperAsSpan with 390.8 ns, then FirstCharToCharArray at 522.5 ns.
Thank you for this Joel. Yes, this method comes in second place, and it doesn’t allocate more memory than other ones. That’s a great suggestion and to be honest, it never crossed my mind. Yes, you use span here as well, which we covered but in a different and obviously faster way. Thanks one more time.
I knew the unsafe method would be the fastest, but I wouldn’t have guessed by how much.
But the real surprise was how badly FirstCharToUpper did. (I was sure it would come in second place). I do note that it is the only one in which you used an interpolated string and “{input[1..]}” and I wonder if that’s the problem.
I absolutely refuse to believe that “input.FirstOrDefault().ToString().ToUpper()” in faster that “Char.ToUpper(input[0]))”
Hi James. Well, I just tested that method with Substring(1) instead of the input[1…] and it was still the last. It was quite faster with the Substring than with the [1…] but still it was the last one.