Last active
November 12, 2015 12:39
-
-
Save neuecc/de75ac9db8a9accac781 to your computer and use it in GitHub Desktop.
DictionaryDisposable
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class DictionaryDisposable<TKey, TValue> : IDisposable, IDictionary<TKey, TValue> | |
where TValue : IDisposable | |
{ | |
bool isDisposed = false; | |
readonly Dictionary<TKey, TValue> inner; | |
public DictionaryDisposable() | |
{ | |
inner = new Dictionary<TKey, TValue>(); | |
} | |
public DictionaryDisposable(IEqualityComparer<TKey> comparer) | |
{ | |
inner = new Dictionary<TKey, TValue>(comparer); | |
} | |
public TValue this[TKey key] | |
{ | |
get | |
{ | |
lock (inner) | |
{ | |
return inner[key]; | |
} | |
} | |
set | |
{ | |
lock (inner) | |
{ | |
if (isDisposed) value.Dispose(); | |
TValue oldValue; | |
if (TryGetValue(key, out oldValue)) | |
{ | |
oldValue.Dispose(); | |
inner[key] = value; | |
} | |
else | |
{ | |
inner[key] = value; | |
} | |
} | |
} | |
} | |
public int Count | |
{ | |
get | |
{ | |
lock (inner) | |
{ | |
return inner.Count; | |
} | |
} | |
} | |
public Dictionary<TKey, TValue>.KeyCollection Keys | |
{ | |
get | |
{ | |
throw new NotSupportedException("please use .Select(x => x.Key).ToArray()"); | |
} | |
} | |
public Dictionary<TKey, TValue>.ValueCollection Values | |
{ | |
get | |
{ | |
throw new NotSupportedException("please use .Select(x => x.Value).ToArray()"); | |
} | |
} | |
public void Add(TKey key, TValue value) | |
{ | |
lock (inner) | |
{ | |
if (isDisposed) | |
{ | |
value.Dispose(); | |
return; | |
} | |
inner.Add(key, value); | |
} | |
} | |
public void Clear() | |
{ | |
lock (inner) | |
{ | |
foreach (var item in inner) | |
{ | |
item.Value.Dispose(); | |
} | |
inner.Clear(); | |
} | |
} | |
public bool Remove(TKey key) | |
{ | |
lock (inner) | |
{ | |
TValue oldValue; | |
if (inner.TryGetValue(key, out oldValue)) | |
{ | |
var isSuccessRemove = inner.Remove(key); | |
if (isSuccessRemove) | |
{ | |
oldValue.Dispose(); | |
} | |
return isSuccessRemove; | |
} | |
else | |
{ | |
return false; | |
} | |
} | |
} | |
public bool ContainsKey(TKey key) | |
{ | |
lock (inner) | |
{ | |
return inner.ContainsKey(key); | |
} | |
} | |
public bool TryGetValue(TKey key, out TValue value) | |
{ | |
lock (inner) | |
{ | |
return inner.TryGetValue(key, out value); | |
} | |
} | |
public Dictionary<TKey, TValue>.Enumerator GetEnumerator() | |
{ | |
lock (inner) | |
{ | |
return new Dictionary<TKey, TValue>(inner).GetEnumerator(); | |
} | |
} | |
bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly | |
{ | |
get | |
{ | |
return ((ICollection<KeyValuePair<TKey, TValue>>)inner).IsReadOnly; | |
} | |
} | |
ICollection<TKey> IDictionary<TKey, TValue>.Keys | |
{ | |
get | |
{ | |
throw new NotSupportedException("please use .Select(x => x.Key).ToArray()"); | |
} | |
} | |
ICollection<TValue> IDictionary<TKey, TValue>.Values | |
{ | |
get | |
{ | |
throw new NotSupportedException("please use .Select(x => x.Value).ToArray()"); | |
} | |
} | |
#if !UNITY_METRO | |
public void GetObjectData(SerializationInfo info, StreamingContext context) | |
{ | |
lock (inner) | |
{ | |
((ISerializable)inner).GetObjectData(info, context); | |
} | |
} | |
public void OnDeserialization(object sender) | |
{ | |
lock (inner) | |
{ | |
((IDeserializationCallback)inner).OnDeserialization(sender); | |
} | |
} | |
#endif | |
void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item) | |
{ | |
Add((TKey)item.Key, (TValue)item.Value); | |
} | |
bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item) | |
{ | |
lock (inner) | |
{ | |
return ((ICollection<KeyValuePair<TKey, TValue>>)inner).Contains(item); | |
} | |
} | |
void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) | |
{ | |
lock (inner) | |
{ | |
((ICollection<KeyValuePair<TKey, TValue>>)inner).CopyTo(array, arrayIndex); | |
} | |
} | |
IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator() | |
{ | |
lock (inner) | |
{ | |
return ((ICollection<KeyValuePair<TKey, TValue>>)inner).ToList().GetEnumerator(); | |
} | |
} | |
IEnumerator IEnumerable.GetEnumerator() | |
{ | |
return GetEnumerator(); | |
} | |
bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item) | |
{ | |
throw new NotSupportedException(); | |
} | |
public void Dispose() | |
{ | |
lock (inner) | |
{ | |
if (isDisposed) return; | |
isDisposed = true; | |
foreach (var item in inner) | |
{ | |
item.Value.Dispose(); | |
} | |
inner.Clear(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment