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

时间:2011-09-18 22:45:33

标签: c# dictionary

我只想删除一个值..之后我不需要使用该变量。为什么不包含不需要第二个参数的过载?

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

功能:http://msdn.microsoft.com/en-us/library/dd287129.aspx

4 个答案:

答案 0 :(得分:26)

您可以创建所需的方法:

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

答案 1 :(得分:22)

C#7添加了丢弃句法糖

现在你可以写:

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

Reference

  

我们允许&#34;丢弃&#34;作为out参数,以_,to的形式   让你忽略你不关心的参数:

     

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

答案 2 :(得分:7)

如果您对删除的值不感兴趣,只需致电ITypeSymbol即可。它被遮蔽了,所以你必须明确地调用它。

示例:

IDictionary.Remove(key)

var dict = new ConcurrentDictionary<string, string>(); dict.AddOrUpdate("mykey", (val) => "test", (val1, val2) => "test"); ((IDictionary)dict).Remove("mykey"); 方法可以帮助您反馈操作是否发生了任何变化。使用最适合您需求的那个。

答案 3 :(得分:0)

我认为第二个参数是必需的,因为您可能需要对要从ConcurrentDictionary中删除的商品进行某些处理。

例如,假设您有一个ConcurrentDictionary<int, MyDisposable>,其中MyDisposable实现了IDisposableConcurrentDictionary.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

}