I only want to remove a value.. I don\'t need to use the variable afterwards. Why not include an overload where this second parameter was not required?
Do I really h
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
I believe the 2nd argument is required is because you may need to do something with the item that you're removing from ConcurrentDictionary
.
For example, imagine you have a ConcurrentDictionary<int, MyDisposable>
where MyDisposable
implements IDisposable
. ConcurrentDictionary.TryRemove(...)
doesn't call .Dispose();
on the item being removed from the dictionary.
In the code below, the .Dispose();
call succeeds because the MyDisposable
hasn't been disposed, yet.
void Main()
{
var dict = new ConcurrentDictionary<int, MyDisposable>();
dict.TryAdd(1, new MyDisposable());
dict.TryRemove(1, out var d);
d.Dispose();
}
public class MyDisposable : IDisposable {
#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// TODO: dispose managed state (managed objects).
}
// TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
// TODO: set large fields to null.
disposedValue = true;
}
}
// TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
// ~MyDisposable()
// {
// // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
// Dispose(false);
// }
// This code added to correctly implement the disposable pattern.
public void Dispose()
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(true);
// TODO: uncomment the following line if the finalizer is overridden above.
// GC.SuppressFinalize(this);
}
#endregion
}
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.
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);
}
}