C# GUID — generate, parse, format, and compare GUIDs
A GUID (Globally Unique Identifier) is a 128-bit value used to uniquely identify objects — database rows, entities, correlation IDs, file names, and more. C# represents it as the System.Guid struct.
A GUID looks like 3f2504e0-4f89-11d3-9a0c-0305e82c3301 — 32 hex digits arranged in five groups separated by hyphens.
Generate a New GUID
Guid id = Guid.NewGuid();
Console.WriteLine(id); // e.g. 3f2504e0-4f89-11d3-9a0c-0305e82c3301Every call to Guid.NewGuid() produces a cryptographically random, practically unique value.
GUID as a String
ToString Formats
Guid g = Guid.NewGuid();
Console.WriteLine(g.ToString()); // "D" — default: 32 hex digits, 4 hyphens
Console.WriteLine(g.ToString("D")); // same as default
Console.WriteLine(g.ToString("N")); // no hyphens: 32 hex digits
Console.WriteLine(g.ToString("B")); // braces: {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
Console.WriteLine(g.ToString("P")); // parentheses: (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
Console.WriteLine(g.ToString("X")); // hex struct: {0x...,0x...,0x...,{0x...,...}}| Format | Example output |
|---|---|
D (default) | 3f2504e0-4f89-11d3-9a0c-0305e82c3301 |
N | 3f2504e04f8911d39a0c0305e82c3301 |
B | {3f2504e0-4f89-11d3-9a0c-0305e82c3301} |
P | (3f2504e0-4f89-11d3-9a0c-0305e82c3301) |
Store as Compact String
The N format is useful when storing in URLs, file names, or databases that don't support a native UUID type.
string compact = Guid.NewGuid().ToString("N");
Console.WriteLine(compact); // e.g. 3f2504e04f8911d39a0c0305e82c3301Parse a GUID from a String
Use Guid.Parse() when the input is guaranteed valid, or Guid.TryParse() when it might not be.
// Parse — throws FormatException if input is invalid
Guid parsed = Guid.Parse("3f2504e0-4f89-11d3-9a0c-0305e82c3301");
Console.WriteLine(parsed);
// TryParse — safe, returns false on failure
if (Guid.TryParse("not-a-guid", out Guid result))
Console.WriteLine($"Parsed: {result}");
else
Console.WriteLine("Invalid GUID"); // prints this
// TryParseExact — enforce a specific format
if (Guid.TryParseExact("3f2504e04f8911d39a0c0305e82c3301", "N", out Guid exact))
Console.WriteLine($"N-format: {exact}");Guid.Empty
Guid.Empty is all zeros — useful as a sentinel "no value" without using null.
Console.WriteLine(Guid.Empty); // 00000000-0000-0000-0000-000000000000
Console.WriteLine(Guid.Empty == default(Guid)); // True
// Check if a GUID has been set
Guid id = Guid.Empty;
if (id == Guid.Empty)
Console.WriteLine("ID not yet assigned");
// Nullable alternative when you need real null semantics
Guid? optionalId = null;Comparing GUIDs
Guid a = Guid.NewGuid();
Guid b = Guid.NewGuid();
Guid c = a; // copy
Console.WriteLine(a == b); // False — different values
Console.WriteLine(a == c); // True — same value
Console.WriteLine(a != b); // True
Console.WriteLine(a.Equals(c)); // True
// Sorting
var guids = new List<Guid> { b, a, c };
guids.Sort();
// GUID implements IComparable<Guid> — sorts by byte valueGUID in a Class / Record
public record Product(Guid Id, string Name, decimal Price);
// Generate ID at creation time
var product = new Product(Guid.NewGuid(), "Laptop", 999.99m);
Console.WriteLine(product.Id); // unique GUID
Console.WriteLine(product.Name); // Laptop
// For APIs, serialize the GUID as a string
string json = System.Text.Json.JsonSerializer.Serialize(product);
// {"Id":"3f2504e0-4f89-11d3-9a0c-0305e82c3301","Name":"Laptop","Price":999.99}GUID as a Dictionary Key
var cache = new Dictionary<Guid, string>();
Guid key = Guid.NewGuid();
cache[key] = "cached value";
if (cache.TryGetValue(key, out string? value))
Console.WriteLine(value); // cached valueGuid implements GetHashCode() efficiently — perfectly safe and performant as a dictionary key.
Performance Tips
Avoid calling ToString() in hot paths
// Slower — allocates a string on every call
void LogId(Guid id)
{
Console.WriteLine(id.ToString()); // allocation
}
// Better — pass Guid directly; only convert when needed for output
void LogId(Guid id)
{
if (logger.IsEnabled)
logger.Write(id.ToString("N")); // only allocates when actually logging
}Use Guid.NewGuid() vs sequential GUIDs
Standard Guid.NewGuid() is random (v4). For database primary keys, random GUIDs cause index fragmentation. In SQL Server, prefer NEWSEQUENTIALID() server-side, or UuidCreateSequential on the application side.
// .NET 9+: sequential GUID for database use
// Guid.CreateVersion7() — time-ordered v7 GUID
// (available in .NET 9 via Guid.CreateVersion7())Common Mistakes
// ❌ Comparing GUIDs as raw strings — case sensitive
string g1 = "3F2504E0-4F89-11D3-9A0C-0305E82C3301";
string g2 = "3f2504e0-4f89-11d3-9a0c-0305e82c3301";
Console.WriteLine(g1 == g2); // False — string compare is case-sensitive!
// ✅ Parse first, then compare
Console.WriteLine(Guid.Parse(g1) == Guid.Parse(g2)); // True
// ❌ Using ToString() format without specifying — format varies by culture
// ✅ Always specify format when you need a predictable string
string id = guid.ToString("D"); // always hyphenated lowercase