C# Dictionary Clear: Syntax, Behavior, and Performance
c# dictionary clear: Learn how to clear a C# Dictionary with the Clear method, understand its memory behavior, and compare it with reassigning a new dictionary.
The c# dictionary clear operation is straightforward: call the Clear() method on a Dictionary<TKey, TValue> instance. This removes all keys and values, leaving the dictionary empty but still usable. Here's 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 internal state is reset, but the instance itself 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 allocated for the internal buckets. The dictionary's internal arrays are retained to avoid reallocation when you add new items later. This is a deliberate design choice: clearing a dictionary is meant to be a fast reset, not a full deallocation.
The method sets each entry's key and value to default, updates the internal free list, and resets the version counter. The version counter is used by enumerators to detect concurrent modifications. If you are iterating over the dictionary and call Clear() from another thread, you may get an InvalidOperationException due to the version change.
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. This can be beneficial 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, which means a new allocation. If you clear and refill a dictionary frequently, reusing the same instance with Clear() avoids repeated allocations and can reduce garbage collection pressure. The trade-off is that the old internal arrays remain 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 to release memory sooner.
- If the dictionary is small, the difference is negligible, and readability should guide your choice.
There is no built-in method to force the dictionary to shrink its internal capacity after Clear(). If you need to release memory explicitly, you can call TrimExcess() on .NET Core 3.0 and later, but that is 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 the comparer. This is important 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. If you need concurrent access, use ConcurrentDictionary<TKey, TValue> instead.
ConcurrentDictionary does not have a Clear() method that atomically empties the collection. The recommended approach is to reassign the reference to a new instance, which is an atomic operation in .NET if the reference is volatile or accessed through Volatile.Read/Volatile.Write. This is a common pattern for cache resets.
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> is designed for persistent data structures. It does not have a Clear() method either. Instead, you can use ImmutableDictionary.Create<TKey, TValue>() to get an empty instance, or call RemoveRange with all keys. Reassigning the reference is the simplest approach.
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 releases the old dictionary's memory and starts fresh. The choice depends on whether you anticipate immediate reuse.