C#  

Stop Looping: Use Dictionary<Guid, T> for Fast Entity Access in .NET

In many .NET applications, you manage collections of entities, like users, orders, or products, and frequently need to look up items by their unique identifiers. 

It’s tempting to just use a List<T> or Collection<T>, especially when you're adding items sequentially.

But here’s the issue: as your data grows, these lookups can quietly cause performance issues.

In this article, I’ll walk you through a common mistake I see in .NET codebases and explain why replacing this:

public Collection<EntityBase> Entities { get; init; }

With this

private readonly IReadOnlyDictionary<Guid, EntityBase> entityLookup;

Can dramatically improve your application’s performance and clarity.

Let's say you have a list of 1,000 EntityBase instances:

var result = entities.FirstOrDefault(e => e.Id == requestedId);

Seems harmless, right?

But here's the hidden issue

  • Every call to FirstOrDefault() does a linear scan of the list.
  • If you're making this lookup often (in an API, a service), you're adding up O(n) costs repeatedly.
  • And many devs don't realize how often this occurs until performance problems appear in production.
  • And the more projects you have, the slower it gets.

Worse: if you're doing this lookup inside a loop or nested service calls, you're silently building a performance bottleneck.

The fix?

Switch to a Dictionary for fast, constant-time lookups.

Instead of this

public class MyService
{
    public List<EntityBase> Entities { get; } = new();

    public EntityBase? GetById(Guid id)
        => Entities.FirstOrDefault(e => e.Id == id);
}

Do this

public class MyService
{
    private readonly Dictionary<Guid, EntityBase> entityLookup;

    public MyService(IEnumerable<EntityBase> entities)
    {
        entityLookup = entities.ToDictionary(e => e.Id);
    }

    public EntityBase? GetById(Guid id)
        => entityLookup.TryGetValue(id, out var entity) ? entity : null;
}

This is cleaner, faster, and shows intent more clearly.

Bonus: For extra safety, wrap your lookup in an IReadOnlyDictionary and initialize it once:

private readonly IReadOnlyDictionary<Guid, EntityBase> _entityLookup;

Now when not to use a Dictionary?

To be fair, Dictionary is not always the best tool. Avoid it when:

  • You care about order of insertion and need indexed access (list[0])
  • Your objects don’t have unique keys
  • You have a small collection and performance is irrelevant

Use the right tool for the right job.