| File: Collections\ReadOnlyEmptyDictionary.cs | Web Access |
| Project: src\msbuild\src\Framework\Microsoft.Build.Framework.csproj (Microsoft.Build.Framework) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Collections; using System.Collections.Generic; using System.Linq; #nullable disable namespace Microsoft.Build.Collections { /// <summary> /// A special singleton enumerable that enumerates a read-only empty dictionary /// </summary> /// <typeparam name="K">Key</typeparam> /// <typeparam name="V">Value</typeparam> internal class ReadOnlyEmptyDictionary<K, V> : IDictionary<K, V>, IReadOnlyDictionary<K, V>, IDictionary { /// <summary> /// The single instance /// </summary> private static readonly Dictionary<K, V> s_backing = new Dictionary<K, V>(); /// <summary> /// The single instance /// </summary> private static ReadOnlyEmptyDictionary<K, V> s_instance; /// <summary> /// Private default constructor as this is a singleton /// </summary> private ReadOnlyEmptyDictionary() { } /// <summary> /// Get the instance /// </summary> public static ReadOnlyEmptyDictionary<K, V> Instance { get { if (s_instance == null) { s_instance = new ReadOnlyEmptyDictionary<K, V>(); } return s_instance; } } /// <summary> /// Empty returns zero /// </summary> public int Count { get { return 0; } } /// <summary> /// Returns true /// </summary> public bool IsReadOnly { get { return true; } } /// <summary> /// Gets empty collection /// </summary> public ICollection<K> Keys => Array.Empty<K>(); /// <summary> /// Gets empty collection /// </summary> public ICollection<V> Values => Array.Empty<V>(); /// <summary> /// Is it fixed size /// </summary> public bool IsFixedSize { get { return true; } } /// <summary> /// Not synchronized /// </summary> public bool IsSynchronized { get { return false; } } /// <summary> /// No sync root /// </summary> public object SyncRoot { get { return null; } } /// <summary> /// Keys /// </summary> ICollection IDictionary.Keys { get { return (ICollection)((IDictionary<K, V>)this).Keys; } } /// <summary> /// Values /// </summary> ICollection IDictionary.Values { get { return (ICollection)((IDictionary<K, V>)this).Values; } } /// <summary> /// Keys /// </summary> IEnumerable<K> IReadOnlyDictionary<K, V>.Keys { get { return Keys; } } /// <summary> /// Values /// </summary> IEnumerable<V> IReadOnlyDictionary<K, V>.Values { get { return Values; } } /// <summary> /// Indexer /// </summary> public object this[object key] { get { return ((IDictionary<K, V>)this)[(K)key]; } set { ((IDictionary<K, V>)this)[(K)key] = (V)value; } } /// <summary> /// Get returns null as read-only /// Set is prohibited and throws. /// </summary> public V this[K key] { get { // Trigger KeyNotFoundException return new Dictionary<K, V>()[key]; } set { throw new InvalidOperationException(SR.CollectionIsReadOnly); } } /// <summary> /// Pass through for underlying collection /// </summary> public void Add(K key, V value) { throw new InvalidOperationException(SR.CollectionIsReadOnly); } /// <summary> /// Empty returns false /// </summary> public bool ContainsKey(K key) { return false; } /// <summary> /// Prohibited on read only collection: throws /// </summary> public bool Remove(K key) { throw new InvalidOperationException(SR.CollectionIsReadOnly); } /// <summary> /// Empty returns false /// </summary> public bool TryGetValue(K key, out V value) { value = default(V); return false; } /// <summary> /// Prohibited on read only collection: throws /// </summary> public void Add(KeyValuePair<K, V> item) { throw new InvalidOperationException(SR.CollectionIsReadOnly); } /// <summary> /// Prohibited on read only collection: throws /// </summary> public void Clear() { throw new InvalidOperationException(SR.CollectionIsReadOnly); } /// <summary> /// Empty returns false /// </summary> public bool Contains(KeyValuePair<K, V> item) { return false; } /// <summary> /// Empty does nothing /// </summary> public void CopyTo(KeyValuePair<K, V>[] array, int arrayIndex) { } /// <summary> /// Prohibited on read only collection: throws /// </summary> public bool Remove(KeyValuePair<K, V> item) { throw new InvalidOperationException(SR.CollectionIsReadOnly); } /// <summary> /// Get empty enumerator /// </summary> public IEnumerator<KeyValuePair<K, V>> GetEnumerator() { return Enumerable.Empty<KeyValuePair<K, V>>().GetEnumerator(); } /// <summary> /// Get empty enumerator /// </summary> IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } /// <summary> /// Add /// </summary> public void Add(object key, object value) { ((IDictionary<K, V>)this).Add((K)key, (V)value); } /// <summary> /// Contains /// </summary> public bool Contains(object key) { return ((IDictionary<K, V>)this).ContainsKey((K)key); } /// <summary> /// Enumerator /// </summary> IDictionaryEnumerator IDictionary.GetEnumerator() { return ((IDictionary)s_backing).GetEnumerator(); } /// <summary> /// Remove /// </summary> public void Remove(object key) { ((IDictionary<K, V>)this).Remove((K)key); } /// <summary> /// CopyTo /// </summary> public void CopyTo(System.Array array, int index) { // Nothing to do } } }