C# Dictionary Clear: Syntax, Behavior, and Performance
Learn how to clear a C# Dictionary with the Clear() method, understand what happens to memory and capacity, and compare Clear() with reassigning a new dictionary.
To clear a C# Dictionary<TKey, TValue>, call the Clear() method. This removes all keys and values, leaving the dictionary empty but still usable. Here is the basic syntax:
var config = new Dictionary<string, string>(); config["mode"] = "production"; config["retries"] = "3"; config.Clear(); Console.WriteLine(config.Count); // 0
After Clear(), the Count property is 0, and you can immediately add new entries. The dictionary's instance remains valid; this is different from setting the reference to null or creating a new dictionary.
What Clear() Does Under the Hood
When you call Clear(), the .NET runtime does not necessarily release the memory used by the dictionary's internal storage. The dictionary's capacity generally stays the same so that adding new items later does not require resizing the structure again. This is a deliberate design choice: clearing is meant to be a fast reset, not a full deallocation.
Clear() removes the stored entries and resets the dictionary's internal bookkeeping. The runtime uses an internal version number to detect modifications, so modifying a dictionary while it is being enumerated can cause an InvalidOperationException.
Clear() vs. Reassigning a New Dictionary
A common alternative is to assign a new dictionary to the variable:
config = new Dictionary<string, string>();
Both approaches result in an empty dictionary, but they differ in memory behavior. When you reassign, the old dictionary becomes eligible for garbage collection if no other references exist. That can be useful if you want to release the memory used by the dictionary's internal arrays, especially if the dictionary was large and you intend to keep it empty for a long time.
However, reassigning creates a new object and therefore a new allocation. If you frequently clear and refill a dictionary, reusing the same instance with Clear() avoids repeated allocations and can reduce garbage collection pressure. The trade-off is that the existing storage remains allocated until you add new items or the dictionary itself is collected.
Performance and Memory Considerations
The choice between Clear() and reassignment depends on your usage pattern:
- If you clear a dictionary and then immediately repopulate it with a similar number of items,
Clear()is usually more efficient because it reuses the existing internal storage. - If you clear a dictionary and then keep it empty for a long time, reassigning may be better because it releases the old memory sooner.
- If the dictionary is small, the difference is negligible, and readability should guide your choice.
Clear() does not shrink the dictionary's capacity. To reduce internal capacity on .NET Core 3.0 and later, you can call TrimExcess() after Clear() as a separate operation.
Clearing a Dictionary with a Custom Equality Comparer
When you create a dictionary with a custom IEqualityComparer<TKey>, Clear() works the same way. The comparer is retained, so you do not need to recreate the dictionary to preserve it. This matters if the comparer holds state or is expensive to construct.
var comparer = StringComparer.OrdinalIgnoreCase; var lookup = new Dictionary<string, int>(comparer); lookup["key"] = 1; lookup.Clear(); lookup["KEY"] = 2; // still works because comparer is retained
If you reassign a new dictionary, you must remember to pass the comparer again, which is a common source of bugs.
Concurrency and Thread Safety When Clearing
Dictionary<TKey, TValue> is not thread-safe for concurrent reads and writes. Calling Clear() while another thread is reading or writing can cause undefined behavior, including exceptions or corrupted state. For concurrent scenarios, use ConcurrentDictionary<TKey, TValue> instead.
ConcurrentDictionary<TKey, TValue> has a thread-safe Clear() method, so you can remove all entries without replacing the instance. If you need to swap the whole dictionary reference instead—for example, to make a new empty cache visible to readers—assign the new instance to a volatile field or use Volatile.Read/Volatile.Write so all threads observe the update.
Clearing a ReadOnlyDictionary or ImmutableDictionary
ReadOnlyDictionary<TKey, TValue> is a wrapper around an existing dictionary and does not expose a Clear() method. To clear it, you must clear the underlying dictionary if you have a reference to it, or replace the entire wrapper.
ImmutableDictionary<TKey, TValue> does not mutate in place. It provides a Clear() method, but the method returns a new empty dictionary rather than modifying the original. Reassign the result to the same variable to make the cleared version active:
lookup = lookup.Clear();
If you do not reassign, the original reference still contains the old entries. You can also use ImmutableDictionary.Create<TKey, TValue>(), but Clear() is the direct way to clear an existing immutable dictionary.
Practical Example: Clearing a Cache
Consider a simple in-memory cache that stores API responses. You might want to clear the cache when the underlying data changes.
public class ApiCache { private Dictionary<string, string> _cache = new(); public string Get(string key) => _cache.TryGetValue(key, out var value) ? value : null; public void Set(string key, string value) => _cache[key] = value; public void Reset() { _cache.Clear(); } }
Using Clear() here keeps the _cache instance alive, which is fine if the cache is repopulated quickly. If the cache is expected to stay empty for a long time, you might prefer to reassign:
public void Reset() { _cache = new Dictionary<string, string>(); }
This lets the old dictionary be garbage-collected and starts fresh. The choice depends on whether you anticipate immediate reuse.