Stop wasting time digging into complex collections in the VS Watch Window!

I’ve always hated comparing two collection during debugging…

Working with Visual Studio’s Watch window is relatively easy when you’re working with small, flat collections – but understanding and finding data in complex collections with complex objects and/or thousands of items is nearly impossible!

You end up staring at something like this:


And then you find yourself spending your time expanding a million nodes and copying bits of information onto a piece of paper, just so that you can compare different bits of data and find out what state your code has changed. It’s a nightmare!

How did we get to this point?

A while ago, my team had a bug in our application:
After a collection of items were marked for removal, some items from that collection were left in the application’s memory – inside the application’s HashSet.
The hard part was figuring what happened to those items!

Thus, my journey to figure out the cause of the issue started!
Keep in mind that I can’t share actual code, instead I’ll share similar, mock code I’ve created to explain the issue we’ve faced and how we’ve managed to solve it.

The data being debugged

Each item has the following properties: two doubles, an enum and another class.
The collection item and the inner class are overriding the equals method and providing a comparison based on property values.


To illustrate the problem we had, I’ve wrote a small console application.
The main method looks like this:

SimpleItemsProvider simpleItemsProvider = new SimpleItemsProvider();
CopiedItemsProvider copiedItemsProvider = new CopiedItemsProvider();

List<CollectionItem> items = ItemsCreator.CreateItems(9481);

List<CollectionItem> simpleItems = simpleItemsProvider.GetItems();
List<CollectionItem> copiedItems = copiedItemsProvider.GetItems();

HashSet<CollectionItem> simpleItemsHash = new HashSet<CollectionItem>(simpleItems);
copiedItems.ForEach(copiedItem => simpleItemsHash.Remove(copiedItem));

Console.WriteLine($"Number of items left: {simpleItemsHash.Count}.");

In short, the above code do the following:

  1. Creates to different item providers.
  2. Gets items from a service. (ItemsCreator in our case)
  3. Sets the items to both providers.
  4. Gets the items from those providers.
  5. Convert one of the collections to a HashSet.
  6. Tries to remove all the items in the HashSet by using the other list of items.
  7. Prints the number of items left in the HashSet.

If we run this program, we can see right away the problem.
Since those items are the same, we expect the print text to be: “Number of items left: 0.”


So, how should I tackle this?

First of all, we need to understand that those collection, although they should be, are not the same object.

Let’s start by checking the items I can’t remove in the simpleItemsHash HashSet.
To make my life easier, I’ll use OzCode’s reveal feature, which enables me to preview specific properties in objects, without digging for the data of each item.
Checking those 10 items turned out to be not as helpful as I wished, since there is nothing special about them.

These values are completely random, and all the values seemed plausible.


What now? Let’s check what items are different between the two collection.
But how should I do it?
Sure, I can write a LINQ expression (Or god forbid a foreach loop which initializes a list),
which will check for each item in the copiedItems if it’s contained in the simpleItemsHash,

  1. Create a list out of it,
  2. Run this code,
  3. Check the differences.

Good thing OzCode has a simple compare feature, that shows the differences between the two collections:

comparecopytosimple-start comparecopytosimple-compare

Great! I see a pattern!

It’s clear here, that items from the copiedItems list with the EnumValue property set to “None” are different.
Looks like the CopiedItemsProvider is making trouble for us.
And indeed, checking the SetItems method in CopiedItemsProvider reveals the problem:

public void SetItems(List<CollectionItem> items)
    _copiedItems = items.Select(CreateItemCopy).ToList();

private CollectionItem CreateItemCopy(CollectionItem currentItem, int index)
    MyEnum copiedEnumValue = _randomIndexes.Contains(index) ? MyEnum.None : currentItem.EnumValue;

    return new CollectionItem(currentItem.Key, currentItem.X, currentItem.Y, copiedEnumValue);

Seems like someone decided to change some of the enum values while copying them in the CopiedItemsProvider.
Indeed, taking care of this line, fixes the problem.

private CollectionItem CreateItemCopy(CollectionItem currentItem, int index)
    return new CollectionItem(currentItem.Key, currentItem.X, currentItem.Y, currentItem.EnumValue);



I was pleasantly surprised by how easy it was fixing the collections comparison bug.
From my previous experiences, I knew it could take me quite a while to handle such things,
mostly because of the massive clicking around and code writing it took to accomplish the same exact thing I’ve just did in under 10 minutes.

Happy coding!

Rami Honig


Keep your code in good shape!

Subscribe to our blog and follow the latest news in the .NET debugging industry

Ready to Dive into Your Prod Code?

Easy debugging with full time-travel data

The Exception

A Quarterly Roundup

Subscribe to our quarterly newsletter and hear all about what’s happening around debugging with Ozcode

Share on facebook
Share on twitter
Share on linkedin
Share on email

Recent Posts

Follow Us

Join Ozcode YouTube Channel

Let’s start debugging, it’s free!

Thanks for downloading the OzCode trial!

You’re well on your way to making C# even sharper.

If your download doesn’t start automatically , please use this direct link.

If you’d like to install OzCode but don’t have
administrative privileges on your machine, please contact us.

Get Started for FREE!

Ozcode Logo

This website uses cookies to ensure you get the best experience on our website.