DotNext by .NET Foundation and Contributors

<PackageReference Include="DotNext" Version="5.12.1" />

 ReadOnlyDictionaryView<TKey, TInput, TOutput>

public struct ReadOnlyDictionaryView<TKey, TInput, TOutput> : IReadOnlyDictionary<TKey, TOutput>, IEnumerable<KeyValuePair<TKey, TOutput>>, IEnumerable, IReadOnlyCollection<KeyValuePair<TKey, TOutput>>, IEquatable<ReadOnlyDictionaryView<TKey, TInput, TOutput>>
Represents lazily converted read-only dictionary.
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace DotNext.Collections.Generic { [StructLayout(LayoutKind.Auto)] [NullableContext(1)] [Nullable(0)] public readonly struct ReadOnlyDictionaryView<[Nullable(2)] TKey, [Nullable(2)] TInput, [Nullable(2)] TOutput> : IReadOnlyDictionary<TKey, TOutput>, IEnumerable<KeyValuePair<TKey, TOutput>>, IEnumerable, IReadOnlyCollection<KeyValuePair<TKey, TOutput>>, IEquatable<ReadOnlyDictionaryView<TKey, TInput, TOutput>> { private readonly IReadOnlyDictionary<TKey, TInput> source; private readonly Func<TInput, TOutput> mapper; public TOutput this[TKey key] { get { if (source == null) throw new KeyNotFoundException(); return mapper(source[key]); } } public IEnumerable<TKey> Keys { get { IReadOnlyDictionary<TKey, TInput> readOnlyDictionary = source; return ((readOnlyDictionary != null) ? readOnlyDictionary.Keys : null) ?? Enumerable.Empty<TKey>(); } } public IEnumerable<TOutput> Values { get { if (source != null && mapper != null) return Enumerable.Select<TInput, TOutput>(source.Values, mapper); return Enumerable.Empty<TOutput>(); } } public int Count { get { IReadOnlyDictionary<TKey, TInput> readOnlyDictionary = source; if (readOnlyDictionary == null) return 0; return readOnlyDictionary.Count; } } public ReadOnlyDictionaryView(IReadOnlyDictionary<TKey, TInput> dictionary, Func<TInput, TOutput> mapper) { if (dictionary == null) throw new ArgumentNullException("dictionary"); source = dictionary; if (mapper == null) throw new ArgumentNullException("mapper"); this.mapper = mapper; } public ReadOnlyDictionaryView(IReadOnlyDictionary<TKey, TInput> dictionary, Converter<TInput, TOutput> mapper) { this = new ReadOnlyDictionaryView<TKey, TInput, TOutput>(dictionary, Unsafe.As<Func<TInput, TOutput>>((object)mapper)); } public bool ContainsKey(TKey key) { return source?.ContainsKey(key) ?? false; } private static IEnumerator<KeyValuePair<TKey, TOutput>> GetEnumerator(IReadOnlyDictionary<TKey, TInput> source, Func<TInput, TOutput> mapper) { foreach (KeyValuePair<TKey, TInput> item in (IEnumerable<KeyValuePair<TKey, TInput>>)source) { item.Deconstruct(out TKey key, out TInput value); TKey key2 = key; TInput arg = value; yield return new KeyValuePair<TKey, TOutput>(key2, mapper(arg)); } } [return: Nullable(new byte[] { 1, 0, 1, 1 })] public IEnumerator<KeyValuePair<TKey, TOutput>> GetEnumerator() { IReadOnlyDictionary<TKey, TInput> readOnlyDictionary = source; bool flag = (readOnlyDictionary == null || readOnlyDictionary.Count == 0) ? true : false; if (!flag && mapper != null) return GetEnumerator(source, mapper); return Enumerable.Empty<KeyValuePair<TKey, TOutput>>().GetEnumerator(); } public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TOutput value) { if (source != null && source.TryGetValue(key, out TInput value2)) { value = mapper(value2); return true; } value = default(TOutput); return false; } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } private bool Equals([In] [IsReadOnly] ref ReadOnlyDictionaryView<TKey, TInput, TOutput> other) { if (source == other.source) return mapper == other.mapper; return false; } public bool Equals([Nullable(new byte[] { 0, 1, 1, 1 })] ReadOnlyDictionaryView<TKey, TInput, TOutput> other) { return Equals(ref other); } public override int GetHashCode() { return RuntimeHelpers.GetHashCode(source) ^ mapper.GetHashCode(); } [NullableContext(2)] public override bool Equals(object other) { if (!(other is ReadOnlyDictionaryView<TKey, TInput, TOutput>)) return object.Equals(source, other); ReadOnlyDictionaryView<TKey, TInput, TOutput> other2 = (ReadOnlyDictionaryView<TKey, TInput, TOutput>)other; return Equals(ref other2); } public static bool operator ==([In] [IsReadOnly] [Nullable(new byte[] { 0, 1, 1, 1 })] ref ReadOnlyDictionaryView<TKey, TInput, TOutput> first, [In] [IsReadOnly] [Nullable(new byte[] { 0, 1, 1, 1 })] ref ReadOnlyDictionaryView<TKey, TInput, TOutput> second) { return first.Equals(ref second); } public static bool operator !=([In] [IsReadOnly] [Nullable(new byte[] { 0, 1, 1, 1 })] ref ReadOnlyDictionaryView<TKey, TInput, TOutput> first, [In] [IsReadOnly] [Nullable(new byte[] { 0, 1, 1, 1 })] ref ReadOnlyDictionaryView<TKey, TInput, TOutput> second) { return !first.Equals(ref second); } } }