ObservableDictionary<TKey, TValue>
class ObservableDictionary<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable, INotifyCollectionChanged, INotifyPropertyChanged, IDictionary, ICollection
An implementation of an observable dictionary.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
namespace NJsonSchema.Collections
{
internal class ObservableDictionary<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable, INotifyCollectionChanged, INotifyPropertyChanged, IDictionary, ICollection
{
private IDictionary<TKey, TValue> _dictionary;
protected IDictionary<TKey, TValue> Dictionary => _dictionary;
public ICollection<TKey> Keys => Dictionary.Keys;
ICollection IDictionary.Values {
get {
return ((IDictionary)Dictionary).Values;
}
}
ICollection IDictionary.Keys {
get {
return ((IDictionary)Dictionary).Keys;
}
}
public ICollection<TValue> Values => Dictionary.Values;
public TValue this[TKey key] {
get {
return Dictionary[key];
}
set {
Insert(key, value, false);
}
}
public bool IsFixedSize => false;
public int Count => Dictionary.Count;
public bool IsSynchronized { get; set; }
public object SyncRoot { get; set; }
public bool IsReadOnly => Dictionary.IsReadOnly;
object IDictionary.this[object key] {
get {
return this[(TKey)key];
}
set {
this[(TKey)key] = (TValue)value;
}
}
public event NotifyCollectionChangedEventHandler CollectionChanged {
[CompilerGenerated]
add {
NotifyCollectionChangedEventHandler notifyCollectionChangedEventHandler = this.CollectionChanged;
NotifyCollectionChangedEventHandler notifyCollectionChangedEventHandler2;
do {
notifyCollectionChangedEventHandler2 = notifyCollectionChangedEventHandler;
NotifyCollectionChangedEventHandler value2 = (NotifyCollectionChangedEventHandler)Delegate.Combine(notifyCollectionChangedEventHandler2, value);
notifyCollectionChangedEventHandler = Interlocked.CompareExchange<NotifyCollectionChangedEventHandler>(ref this.CollectionChanged, value2, notifyCollectionChangedEventHandler2);
} while ((object)notifyCollectionChangedEventHandler != notifyCollectionChangedEventHandler2);
}
[CompilerGenerated]
remove {
NotifyCollectionChangedEventHandler notifyCollectionChangedEventHandler = this.CollectionChanged;
NotifyCollectionChangedEventHandler notifyCollectionChangedEventHandler2;
do {
notifyCollectionChangedEventHandler2 = notifyCollectionChangedEventHandler;
NotifyCollectionChangedEventHandler value2 = (NotifyCollectionChangedEventHandler)Delegate.Remove(notifyCollectionChangedEventHandler2, value);
notifyCollectionChangedEventHandler = Interlocked.CompareExchange<NotifyCollectionChangedEventHandler>(ref this.CollectionChanged, value2, notifyCollectionChangedEventHandler2);
} while ((object)notifyCollectionChangedEventHandler != notifyCollectionChangedEventHandler2);
}
}
public event PropertyChangedEventHandler PropertyChanged {
[CompilerGenerated]
add {
PropertyChangedEventHandler propertyChangedEventHandler = this.PropertyChanged;
PropertyChangedEventHandler propertyChangedEventHandler2;
do {
propertyChangedEventHandler2 = propertyChangedEventHandler;
PropertyChangedEventHandler value2 = (PropertyChangedEventHandler)Delegate.Combine(propertyChangedEventHandler2, value);
propertyChangedEventHandler = Interlocked.CompareExchange<PropertyChangedEventHandler>(ref this.PropertyChanged, value2, propertyChangedEventHandler2);
} while ((object)propertyChangedEventHandler != propertyChangedEventHandler2);
}
[CompilerGenerated]
remove {
PropertyChangedEventHandler propertyChangedEventHandler = this.PropertyChanged;
PropertyChangedEventHandler propertyChangedEventHandler2;
do {
propertyChangedEventHandler2 = propertyChangedEventHandler;
PropertyChangedEventHandler value2 = (PropertyChangedEventHandler)Delegate.Remove(propertyChangedEventHandler2, value);
propertyChangedEventHandler = Interlocked.CompareExchange<PropertyChangedEventHandler>(ref this.PropertyChanged, value2, propertyChangedEventHandler2);
} while ((object)propertyChangedEventHandler != propertyChangedEventHandler2);
}
}
public ObservableDictionary()
{
_dictionary = new Dictionary<TKey, TValue>();
}
public ObservableDictionary(IDictionary<TKey, TValue> dictionary)
{
_dictionary = new Dictionary<TKey, TValue>(dictionary);
}
public ObservableDictionary(IEqualityComparer<TKey> comparer)
{
_dictionary = new Dictionary<TKey, TValue>(comparer);
}
public ObservableDictionary(int capacity)
{
_dictionary = new Dictionary<TKey, TValue>(capacity);
}
public ObservableDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer)
{
_dictionary = new Dictionary<TKey, TValue>(dictionary, comparer);
}
public ObservableDictionary(int capacity, IEqualityComparer<TKey> comparer)
{
_dictionary = new Dictionary<TKey, TValue>(capacity, comparer);
}
public void AddRange(IDictionary<TKey, TValue> items)
{
if (items == null)
throw new ArgumentNullException("items");
if (items.Count > 0) {
if (Dictionary.Count > 0) {
if (Enumerable.Any<TKey>((IEnumerable<TKey>)items.Keys, (Func<TKey, bool>)((TKey k) => Dictionary.ContainsKey(k))))
throw new ArgumentException("An item with the same key has already been added.");
foreach (KeyValuePair<TKey, TValue> item in items) {
Dictionary.Add(item);
}
} else
_dictionary = new Dictionary<TKey, TValue>(items);
OnCollectionChanged(NotifyCollectionChangedAction.Add, Enumerable.ToArray<KeyValuePair<TKey, TValue>>((IEnumerable<KeyValuePair<TKey, TValue>>)items));
}
}
protected virtual void Insert(TKey key, TValue value, bool add)
{
if (Dictionary.TryGetValue(key, out TValue value2)) {
if (add)
throw new ArgumentException("An item with the same key has already been added.");
if (!object.Equals(value2, value)) {
Dictionary[key] = value;
OnCollectionChanged(NotifyCollectionChangedAction.Replace, new KeyValuePair<TKey, TValue>(key, value), new KeyValuePair<TKey, TValue>(key, value2));
}
} else {
Dictionary[key] = value;
OnCollectionChanged(NotifyCollectionChangedAction.Add, new KeyValuePair<TKey, TValue>(key, value));
}
}
protected virtual void OnPropertyChanged(string propertyName)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected void OnCollectionChanged()
{
OnPropertyChanged();
this.CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
protected void OnCollectionChanged(NotifyCollectionChangedAction action, KeyValuePair<TKey, TValue> changedItem)
{
OnPropertyChanged();
this.CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(action, changedItem, 0));
}
protected void OnCollectionChanged(NotifyCollectionChangedAction action, KeyValuePair<TKey, TValue> newItem, KeyValuePair<TKey, TValue> oldItem)
{
OnPropertyChanged();
this.CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(action, newItem, oldItem, 0));
}
protected void OnCollectionChanged(NotifyCollectionChangedAction action, IList newItems)
{
OnPropertyChanged();
this.CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(action, newItems, 0));
}
private void OnPropertyChanged()
{
OnPropertyChanged("Count");
OnPropertyChanged("Item[]");
OnPropertyChanged("Keys");
OnPropertyChanged("Values");
}
public void Add(TKey key, TValue value)
{
Insert(key, value, true);
}
public bool ContainsKey(TKey key)
{
return Dictionary.ContainsKey(key);
}
public virtual bool Remove(TKey key)
{
if (key == null)
throw new ArgumentNullException("key");
Dictionary.TryGetValue(key, out TValue _);
bool num = Dictionary.Remove(key);
if (num)
OnCollectionChanged();
return num;
}
public bool TryGetValue(TKey key, out TValue value)
{
return Dictionary.TryGetValue(key, out value);
}
public void Add(KeyValuePair<TKey, TValue> item)
{
Insert(item.Key, item.Value, true);
}
void IDictionary.Add(object key, object value)
{
Insert((TKey)key, (TValue)value, true);
}
public void Clear()
{
if (Dictionary.Count > 0) {
Dictionary.Clear();
OnCollectionChanged();
}
}
public void Initialize(IEnumerable<KeyValuePair<TKey, TValue>> keyValuePairs)
{
List<KeyValuePair<TKey, TValue>> pairs = Enumerable.ToList<KeyValuePair<TKey, TValue>>(keyValuePairs);
foreach (KeyValuePair<TKey, TValue> item in pairs) {
Dictionary[item.Key] = item.Value;
}
TKey[] array = Enumerable.ToArray<TKey>(Enumerable.Where<TKey>((IEnumerable<TKey>)Dictionary.Keys, (Func<TKey, bool>)((TKey k) => !Enumerable.Any<KeyValuePair<TKey, TValue>>((IEnumerable<KeyValuePair<TKey, TValue>>)pairs, (Func<KeyValuePair<TKey, TValue>, bool>)((KeyValuePair<TKey, TValue> p) => object.Equals(p.Key, k))))));
foreach (TKey key in array) {
Dictionary.Remove(key);
}
OnCollectionChanged();
}
public void Initialize(IEnumerable keyValuePairs)
{
Initialize(Enumerable.Cast<KeyValuePair<TKey, TValue>>(keyValuePairs));
}
public bool Contains(object key)
{
return ContainsKey((TKey)key);
}
IDictionaryEnumerator IDictionary.GetEnumerator()
{
return ((IDictionary)Dictionary).GetEnumerator();
}
public void Remove(object key)
{
Remove((TKey)key);
}
public bool Contains(KeyValuePair<TKey, TValue> item)
{
return Dictionary.Contains(item);
}
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
Dictionary.CopyTo(array, arrayIndex);
}
public void CopyTo(Array array, int index)
{
((IDictionary)Dictionary).CopyTo(array, index);
}
public bool Remove(KeyValuePair<TKey, TValue> item)
{
return Remove(item.Key);
}
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
return Dictionary.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)Dictionary).GetEnumerator();
}
}
}