Bytes from Strings in C# Without Encoding: Solving the Problem Correctly

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Why is this question so popular on Stack Overflow?



If you've ever written in C# and needed to convert a string to a byte array, you've probably wondered: "Why do I have to specify an encoding? A string is just a string!" This question has garnered thousands of views on Stack Overflow for a reason. It touches on a fundamental misunderstanding between how we see text and how the computer sees it.



In this article, we won't just provide ready-made code; we'll also explain why Encoding.UTF8.GetBytes("hello") is not a workaround, but the only correct approach. You'll learn how to get the byte representation of strings in C# without risking data loss, and what lies behind the magic of "automatic encoding selection."



The Myth of the "Encoding-Free String"



Many beginners think that a string in C# is just a sequence of bytes. This is not true. Internally, string in .NET is stored as UTF-16 (two-byte characters). When you write "Привет", it occupies 12 bytes in memory (6 characters × 2 bytes). But if you try to send this string to a file, network, or database, you'll almost always need a different format — most often UTF-8.



Trying to get bytes "without encoding" is like asking: "How do I translate a book from Russian to English without specifying the language?" It's impossible. Encoding is the set of rules for converting characters to bytes. Without it, you'll get gibberish.



How NOT to do it (a typical mistake)



string text = "Hello, мир!";byte[] wrongBytes = System.Text.Encoding.Default.GetBytes(text); // BAD!


This code uses the system default encoding (usually Windows-1251 on a Russian Windows). If you run this code on another machine or on Linux, you'll get different bytes. Your application will become unpredictable.



The Correct Approach: Explicit Encoding Specification



The only reliable way to get a consistent byte representation of strings is to explicitly specify the encoding. The most popular and recommended option is UTF-8:



string text = "Hello, мир!";byte[] utf8Bytes = System.Text.Encoding.UTF8.GetBytes(text);// Result: [72, 101, 108, 108, 111, 44, 32, 208, 188, 208, 184, 209, 128, 33]


This code will always produce the same result on any platform. Why? Because UTF-8 is an international standard that works the same everywhere.



Other Encoding Options (When They Are Needed)



  • ASCII — Latin only, discards all characters >127.
  • Unicode (UTF-16LE) — C#'s internal format, but inefficient for storage.
  • Windows-1251 — legacy, only for compatibility with older systems.


For 99% of modern tasks, use Encoding.UTF8.



What if I want "without specifying"? Is there a hack?



Technically, you can use BitConverter.ToString() or unsafe code with pointers, but this will give you the raw UTF-16 bytes stored in memory. This is a bad idea for several reasons:



  • The result depends on the platform (Little-Endian vs Big-Endian).
  • You'll get extra null bytes for Latin characters (each character takes 2 bytes).
  • With a change in the .NET version, the internal representation could change (unlikely, but possible).


Example of dangerous code that you should not replicate:



unsafe{    string text = "Hello";    fixed (char* ptr = text)    {        byte* bytePtr = (byte*)ptr;        // Working with raw UTF-16 bytes    }}


This works, but violates the principle of "don't mess with internals if you don't understand the consequences."



Best Practices for Beginners<

Blogs

Book Recommendations