为什么 ConcurrentDictionary.TryRemove 需要第二个输出参数?

问题描述 投票:0回答:5
我只想删除一个值。之后我不需要使用该变量。为什么不包含不需要第二个参数的重载?

我真的必须将其存储在临时局部变量中,而不使用它,并在方法结束时让垃圾收集器收集它吗?看起来很傻..

功能:

ConcurrentDictionary<TKey,TValue>.TryRemove


    

c# dictionary collections concurrentdictionary
5个回答
90
投票
C#7 添加了丢弃语法糖

现在你可以写:

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

参考

我们也允许“丢弃”作为输出参数,以 _ 的形式, 让你忽略你不关心的参数:

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



33
投票
您可以完全创建您想要的方法:

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); } }

更新:或者,正如评论中提到的Dialecticus,只需使用Remove

。但请注意,由于它是显式接口实现,因此您需要对 IDictionary<TKey, TValue>
 的引用,如果您想避免强制转换 
ConcurrentDictionary<TKey, TValue>
 引用,这将导致您返回创建扩展方法:

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

12
投票
如果您对删除的值不感兴趣,只需致电

IDictionary.Remove(key)

。它处于阴影状态,因此您必须显式调用它。

示例:

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

TryRemove(key, out value)

方法可以为您提供操作是否发生任何更改的反馈。使用最适合您需求的一种。


0
投票
我认为第二个参数是必需的,因为您可能需要对要从

ConcurrentDictionary

 中删除的项目执行某些操作。 

例如,假设您有一个

ConcurrentDictionary<int, MyDisposable>

,其中 
MyDisposable
 实现了 
IDisposable
。对于从字典中删除的项目,
ConcurrentDictionary.TryRemove(...)
 不会调用 
.Dispose();

在下面的代码中,

.Dispose();

调用成功,因为
MyDisposable
尚未被释放。 

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 }
    

-3
投票
现在它有一个不

out

任何参数的重载:

public bool TryRemove(KeyValuePair<TKey, TValue> item)
    
© www.soinside.com 2019 - 2024. All rights reserved.