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

C# Example Code
Guid id = Guid.NewGuid();
Console.WriteLine(id); // e.g. 3f2504e0-4f89-11d3-9a0c-0305e82c3301

Every call to Guid.NewGuid() produces a cryptographically random, practically unique value.

GUID as a String

ToString Formats

C# Example Code
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...,...}}
FormatExample output
D (default)3f2504e0-4f89-11d3-9a0c-0305e82c3301
N3f2504e04f8911d39a0c0305e82c3301
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.

C# Example Code
string compact = Guid.NewGuid().ToString("N");
Console.WriteLine(compact); // e.g. 3f2504e04f8911d39a0c0305e82c3301

Parse a GUID from a String

Use Guid.Parse() when the input is guaranteed valid, or Guid.TryParse() when it might not be.

C# Example Code
// 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.

C# Example Code
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

C# Example Code
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 value

GUID in a Class / Record

C# Example Code
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

C# Example Code
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 value

Guid implements GetHashCode() efficiently — perfectly safe and performant as a dictionary key.

Performance Tips

Avoid calling ToString() in hot paths

C# Example Code
// 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.

C# Example Code
// .NET 9+: sequential GUID for database use
// Guid.CreateVersion7() — time-ordered v7 GUID
// (available in .NET 9 via Guid.CreateVersion7())

Common Mistakes

C# Example Code
// ❌ 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