C# UTF-8 String Literals — Complete Guide
In this tutorial, you'll learn about C# UTF. We cover key concepts, practical examples, and best practices.
You send a string over the network or write it to a stream that expects UTF-8 bytes. You call Encoding.UTF8.GetBytes() on every operation, allocating a new byte array each time. UTF-8 string literals (C# 11) give you compile-time UTF-8 byte representations.
Wrong
string json = "{\"type\": \"ping\"}";
byte[] bytes = Encoding.UTF8.GetBytes(json);
await stream.WriteAsync(bytes);
Output: Works. But GetBytes allocates a byte[] every time. If this is in a hot path, it creates GC pressure.
Right
ReadOnlySpan<byte> json = "{\"type\": \"ping\"}"u8;
await stream.WriteAsync(json);
Output: Same bytes, zero allocation. The u8 suffix tells the compiler to produce a UTF-8 encoded ReadOnlySpan<byte> at compile time.
UTF-8 string literals are stored as static data in the assembly — no runtime encoding, no allocation.
// In expressions
HttpClient.PostAsync(url, new ByteArrayContent("data"u8.ToArray()));
// With raw string literals
ReadOnlySpan<byte> json = """
{ "type": "ping" }
"""u8;
Prevention
- Use
"text"u8when you need UTF-8 bytes for network I/O, file writes, or interop. - Use
"text"u8in hot paths whereEncoding.UTF8.GetByteswould allocate. - Use raw string literals
"""..."""u8for multi-line UTF-8 content. - Convert to
byte[]with.ToArray()when the API requires it. - Store as
static readonly byte[]when the same bytes are used repeatedly. - Know that
u8always producesReadOnlySpan<byte>— assign to the right type.
Common Mistakes with utf 8 string
- Forgetting that lazy evaluation defers computation until the value is forced, causing space leaks with unevaluated thunks
- Using
returnto exit a function early instead of wrapping a pure value in the monad - Mixing let bindings with <- bindings in do notation, producing type errors
These mistakes appear frequently in real-world CSHARP code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
UTF-8 string literals are used in Doda Browser's HTTP client for zero-allocation request headers. For more C# performance tips, visit DodaTech.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro