Why does ConcurrentDictionary.TryRemove require a second out argument?

C#7 added discard syntactic sugar

So now you can write:

dictionary.TryRemove(entry.Key, out _); 

Reference

We allow "discards" as out parameters as well, in the form of a _, to let you ignore out parameters you don’t care about:

p.GetCoordinates(out var x, out _); // I only care about x


You can create exactly the method you want:

public static class ConcurrentDictionaryEx {
  public static bool TryRemove<TKey, TValue>(
    this ConcurrentDictionary<TKey, TValue> self, TKey key) {
    TValue ignored;
    return self.TryRemove(key, out ignored);
  }
}

UPDATE: Or, as Dialecticus mentioned in the comments, just use Remove. But note that, since it's an explicit interface implementation, you'll need a reference to an IDictionary<TKey, TValue>, which leads you back to creating an extension method if you want to avoid casting a ConcurrentDictionary<TKey, TValue> reference:

public static class ConcurrentDictionaryEx {
  public static bool Remove<TKey, TValue>(
    this ConcurrentDictionary<TKey, TValue> self, TKey key) {
      return ((IDictionary<TKey, TValue>)self).Remove(key);
  }
}

If you're not interested in the value that was removed, simply call IDictionary.Remove(key). It's shadowed, so you have to invoke it explicitly.

Example:

var dict = new ConcurrentDictionary<string, string>();
dict.AddOrUpdate("mykey", (val) => "test", (val1, val2) => "test");
((IDictionary)dict).Remove("mykey");

The TryRemove(key, out value) method is there to give you feedback whether the operation made any change. Use the one that best suits your needs.