// Copyright (c) Facebook, Inc. and its affiliates // SPDX-License-Identifier: MIT OR Apache-2.0 using System; using System.Collections; using System.Collections.Generic; namespace Serde { /// /// Immutable wrapper class around . Implements value semantics for /// and . /// public class ValueDictionary : IEquatable>, IReadOnlyDictionary where K: IEquatable where V: IEquatable { private readonly Dictionary dict; private int? hashCode; public int Count => dict.Count; public IEnumerable Keys => dict.Keys; public IEnumerable Values => dict.Values; public V this[K key] => dict[key]; public ValueDictionary(Dictionary dictionary) { dict = dictionary ?? throw new ArgumentNullException(nameof(dictionary)); hashCode = null; } public bool ContainsKey(K key) => dict.ContainsKey(key); public bool TryGetValue(K key, out V value) => dict.TryGetValue(key, out value); IEnumerator> IEnumerable>.GetEnumerator() => dict.GetEnumerator(); public IEnumerator GetEnumerator() => ((IEnumerable)dict).GetEnumerator(); public override bool Equals(object obj) => obj is ValueDictionary bytes && Equals(bytes); public bool Equals(ValueDictionary other) { if (other == null) return false; if (Count != other.Count) return false; foreach (var key in Keys) { if (!other.ContainsKey(key)) return false; if (!dict[key].Equals(other[key])) return false; } return true; } public static bool operator ==(ValueDictionary left, ValueDictionary right) => Equals(left, right); public static bool operator !=(ValueDictionary left, ValueDictionary right) => !Equals(left, right); public override int GetHashCode() { unchecked { if (hashCode.HasValue) return hashCode.Value; int code = 45053; foreach (var pair in dict) { code = code * 31 + pair.Key.GetHashCode(); code = code * 31 + pair.Value.GetHashCode(); } hashCode = code; return code; } } } }