<PackageReference Include="NJsonSchema" Version="9.2.4" />

ObservableDictionary<TKey, TValue>

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