ZetCode

C# ToUpper

last modified October 18, 2026

In this article we show how to transform letters to upper case in C#. The C# tutorial is a comprehensive tutorial on the C# language.

The string.ToUpper method returns a copy of a string converted to uppercase. Strings are immutable, so the original string is never changed. The overloaded ToUpper(CultureInfo) uses the casing rules of the specified culture. The ToUpperInvariant method uses the rules of the invariant culture, which do not depend on the machine's settings.

C# ToUpper example

In the following example, we transform the specified strings to uppercase.

Program.cs
var w1 = "stormy weather";
var w2 = "l'écrivain français";
var w3 = "ясный сокол";
var w4 = "červená hviezda";

Console.WriteLine(w1.ToUpper());
Console.WriteLine(w2.ToUpper());
Console.WriteLine(w3.ToUpper());
Console.WriteLine(w4.ToUpper());

We have four strings in four different languages. We change the letters to uppercase with ToUpper.

$ dotnet run
STORMY WEATHER
L'ÉCRIVAIN FRANÇAIS
ЯСНЫЙ СОКОЛ
ČERVENÁ HVIEZDA

All the letters were transformed to uppercase, including the accented and the Cyrillic ones.

C# ToUpper and culture

ToUpper() without arguments uses the current culture, so the same code can give different results on different machines. The best known example is Turkish, which has two letters i: a dotted one and a dotless one. The uppercase of "i" is "İ" (dotted capital), and the uppercase of "ı" (dotless) is "I".

Program.cs
using System.Globalization;

var tr = new CultureInfo("tr-TR");
var us = new CultureInfo("en-US");

string s = "file:title info";

Console.WriteLine(s.ToUpper(us));
Console.WriteLine(s.ToUpper(tr));
Console.WriteLine(s.ToUpperInvariant());

// a classic bug: a culture-sensitive comparison of protocol keywords
CultureInfo.CurrentCulture = tr;
Console.WriteLine("i".ToUpper());
Console.WriteLine("i".ToUpperInvariant());
Console.WriteLine("ı".ToUpper());   // dotless i

Console.WriteLine("TITLE".ToLower(tr));
Console.WriteLine("TITLE".ToLowerInvariant());

// case-insensitive comparison without allocating
Console.WriteLine(string.Equals("title", "TITLE", StringComparison.OrdinalIgnoreCase));

The program converts the same text with three different cultures.

Console.WriteLine(s.ToUpper(us));
Console.WriteLine(s.ToUpper(tr));
Console.WriteLine(s.ToUpperInvariant());

The Turkish culture produces "İ" for every "i". Code that tests the result against an English keyword such as "FILE" then fails on a Turkish computer.

CultureInfo.CurrentCulture = tr;
Console.WriteLine("i".ToUpper());
Console.WriteLine("i".ToUpperInvariant());

After switching the current culture, even the parameterless ToUpper returns "İ". The invariant method is not affected.

Console.WriteLine(string.Equals("title", "TITLE", StringComparison.OrdinalIgnoreCase));

For case-insensitive comparisons, do not convert both strings to upper or lower case. Use StringComparison.OrdinalIgnoreCase (or CurrentCultureIgnoreCase for text meant for people); it is faster and does not allocate new strings.

$ dotnet run
FILE:TITLE INFO
FİLE:TİTLE İNFO
FILE:TITLE INFO
İ
I
I
tıtle
title
True

As a rule, use ToUpperInvariant for identifiers, protocol keywords, file extensions, and dictionary keys, and the culture-aware ToUpper for text that is shown to users.

C# char.ToUpper and special cases

The char.ToUpper and char.ToUpperInvariant methods convert a single character. .NET maps one UTF-16 character to one UTF-16 character, so the conversion has limits.

Program.cs
Console.WriteLine("straße".ToUpperInvariant());      // ß has no single-char uppercase
Console.WriteLine('ß'.ToString().ToUpperInvariant());
Console.WriteLine(char.ToUpperInvariant('ß'));
Console.WriteLine("dž".ToUpperInvariant());
Console.WriteLine(char.ToUpper('a'));
Console.WriteLine(char.IsUpper('A'));

string text = "hello, world 42!";
Console.WriteLine(string.Concat(text.Where(char.IsLetter)).ToUpperInvariant());

The German letter "ß" uppercases to "SS" under full Unicode case mapping, but .NET does not change the length of a string, so it leaves "ß" alone. Likewise, char.ToUpper cannot do anything for characters that are stored as a surrogate pair. If you need full Unicode case mapping, use a library such as ICU directly.

$ dotnet run
STRAßE
ß
ß
DŽ
A
True
HELLOWORLD

The last line filters the letters with char.IsLetter and uppercases the result.

C# ToUpper without allocation

Characters outside the Basic Multilingual Plane, such as the Deseret alphabet, take two char values. string.ToUpperInvariant handles them correctly, while a char-by-char loop does not. The Rune type represents a full Unicode scalar value. The span-based ToUpperInvariant writes into a buffer we provide, so no string is allocated.

Program.cs
using System.Text;
using System.Globalization;

// 𐐨 (Deseret small letter) is outside the BMP: a surrogate pair of two chars
string s = "𐐨a";

Console.WriteLine(s.Length);
Console.WriteLine(s.ToUpperInvariant());
Console.WriteLine(char.ToUpperInvariant(s[0]) == s[0]);   // a char cannot change a surrogate

Span<char> buf = stackalloc char[16];
int n = "stormy weather".AsSpan().ToUpperInvariant(buf);
Console.WriteLine(buf[..n].ToString());

// enumerating text elements
foreach (var rune in s.EnumerateRunes())
{
    Console.WriteLine($"{rune} -> {Rune.ToUpperInvariant(rune)}");
}

The string "𐐨a" has a length of 3 chars, although it contains two characters.

$ dotnet run
3
𐐀A
True
STORMY WEATHER
𐐨 -> 𐐀
a -> A

The check char.ToUpperInvariant(s[0]) == s[0] is True, because the first char is only half of a surrogate pair and cannot be mapped by itself. The rune enumeration gives the correct result.

C# ToTitleCase

The TextInfo.ToTitleCase method converts a string to title case, where the first letter of each word is uppercase.

Program.cs
using System.Globalization;

TextInfo ti = CultureInfo.InvariantCulture.TextInfo;

string[] words = ["stormy weather", "l'écrivain français", "ясный сокол", "červená hviezda",
    "NASA launches rocket", "McDONALD'S"];

foreach (var w in words)
{
    Console.WriteLine(ti.ToTitleCase(w));
}

Console.WriteLine("--");

foreach (var w in words)
{
    Console.WriteLine(ti.ToTitleCase(w.ToLower()));
}

We transform several strings with TextInfo.ToTitleCase, first as they are, then converted to lower case.

TextInfo ti = CultureInfo.InvariantCulture.TextInfo;

The method belongs to the TextInfo class of a culture. We take the one of the invariant culture; for text written in a particular language, use that culture's TextInfo.

$ dotnet run
Stormy Weather
L'écrivain Français
Ясный Сокол
Červená Hviezda
NASA Launches Rocket
Mcdonald's
--
Stormy Weather
L'écrivain Français
Ясный Сокол
Červená Hviezda
Nasa Launches Rocket
Mcdonald's

Note that words written entirely in uppercase, such as "NASA", are treated as acronyms and left unchanged. To normalize them, lower the string first, as in the second block. The method knows nothing about names, so it cannot produce "McDonald's", and it does not skip small words such as "of" or "the".

C# capitalize the first letter

Often, we only want to change the first letter of the first word of a string. For this, we create our own function.

Program.cs
string[] words = ["stormy weather", "l'écrivain français", "ясный сокол", "červená hviezda", "", "éclair"];

foreach (var w in words)
{
    Console.WriteLine($"[{Capitalize(w)}]");
}

static string Capitalize(string s)
{
    if (string.IsNullOrEmpty(s))
    {
        return s;
    }

    return string.Create(s.Length, s, static (span, src) =>
    {
        src.AsSpan().CopyTo(span);
        span[0] = char.ToUpperInvariant(span[0]);
    });
}

The Capitalize function uppercases only the first letter of a string.

return string.Create(s.Length, s, static (span, src) =>
{
    src.AsSpan().CopyTo(span);
    span[0] = char.ToUpperInvariant(span[0]);
});

The string.Create method allocates the new string once and lets us fill its content through a span. We copy the original text and change the first character. This avoids the intermediate array that ToCharArray would create. The empty string is returned unchanged. A shorter alternative that allocates a bit more is char.ToUpper(s[0]) + s[1..].

$ dotnet run
[Stormy weather]
[L'écrivain français]
[Ясный сокол]
[Červená hviezda]
[]
[Éclair]

Source

String.ToUpper method

In this article we have transformed strings to uppercase in C#.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all C# tutorials.