Skip to Content
Course content

205: Encoding Classes: UTF8, ASCII, Unicode

Click on the "Edit" button in the top corner of the screen to edit your slide content.

I can't tell you how many times I've walked into a codebase only to find a "bug" that was actually just a character encoding mismatch. You'll see it in the logs first: a name like "Müller" suddenly becomes "Müller" or, worse, "Mller". It's frustrating because the code looks perfectly fine, but the data is being mangled during the transition from a string in memory to a sequence of bytes on a disk or a network socket.

The "It Works on My Machine" Trap

When you first start working with bytes in C#, the temptation is to reach for Encoding.ASCII because it's simple. If you're just sending basic alphanumeric commands to a legacy piece of hardware, it works great. But the moment you hit a character outside the standard 127-character ASCII set, ASCII doesn't "fail" by throwing an exception—it just replaces the unknown character with a question mark. I've seen entire database migrations ruined because someone used ASCII to save a list of global customer names.

// The naive way: assuming the world is English-only
string customerName = "Sato 佐藤";
byte[] data = Encoding.ASCII.GetBytes(customerName);
string result = Encoding.ASCII.GetString(data);
Console.WriteLine(result); // Output: Sato ??

You might think, "I'll just use Encoding.Default then." Please, don't. Encoding.Default is a gamble. On an older Windows machine in the US, it might be one thing; on a server in Japan, it's another. Relying on the system's default encoding is a recipe for "it works on my machine" bugs that only appear once the code is deployed to a production server in a different region.

Why UTF-8 is the Industry Standard

In almost every professional scenario you'll encounter, Encoding.UTF8 is the correct answer. The beauty of UTF-8 is that it's backward compatible with ASCII—any valid ASCII file is also a valid UTF-8 file—but it can scale up to represent every single character in the Unicode standard. It does this using a variable-width encoding: common English characters take 1 byte, while more complex characters take more. It's the perfect balance between space efficiency and universal compatibility.

// The professional way: Explicitly using UTF-8
string customerName = "Sato 佐藤";
byte[] data = Encoding.UTF8.GetBytes(customerName);
string result = Encoding.UTF8.GetString(data);
Console.WriteLine(result); // Output: Sato 佐藤

When you're writing files or calling an API, always be explicit. Don't let the framework guess. By specifying Encoding.UTF8, you're telling the next developer (and the operating system) exactly how to interpret those bytes, regardless of where the code is running.

The Internal Secret of C# Strings

Here is a bit of a curveball: while we use UTF-8 for storage and transmission, C# doesn't use UTF-8 internally. In .NET, the string type is actually encoded as UTF-16 (which is what Encoding.Unicode refers to). This means every character in a C# string generally takes 2 bytes.

You don't usually need to worry about this because the Encoding classes handle the translation for you. However, it's important to understand the trade-off. UTF-16 is faster for the CPU to index into (since most characters are a fixed size), but it's bloated for storage. That's why we use Encoding.Unicode when we need to match a specific Windows API requirement, but we stick to Encoding.UTF8 for everything else. If you're ever confused about which one to use for a web request or a JSON file, just remember: the internet runs on UTF-8.




📋 Practical Task

Exercise: Fixing the Corrupted User Profile Loader

You have been handed a legacy piece of code that loads user profiles from a text file. The profiles contain international names, but the previous developer used Encoding.ASCII, resulting in corrupted data. Your task is to fix the loader so it correctly handles Unicode characters.

Requirements:

  • Create a file named profiles.txt using File.WriteAllText, ensuring you explicitly save it as UTF-8. The file should contain a string with diverse characters, such as: "User: André, Location: Montréal, Status: 🚀".
  • Write a method LoadProfile() that reads this file.
  • First, implement the read using Encoding.ASCII and print the result to the console to observe the corruption.
  • Then, refactor the method to use Encoding.UTF8 to correctly retrieve the original string.
  • Verify that the output matches the original input exactly.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.