DotNext by Roman Sakno

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

 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)] [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] public readonly struct ReadOnlyDictionaryView<[System.Runtime.CompilerServices.Nullable(2)] TKey, [System.Runtime.CompilerServices.Nullable(2)] TInput, [System.Runtime.CompilerServices.Nullable(2)] TOutput> : IReadOnlyDictionary<TKey, TOutput>, IEnumerable<KeyValuePair<TKey, TOutput>>, IEnumerable, IReadOnlyCollection<KeyValuePair<TKey, TOutput>>, IEquatable<ReadOnlyDictionaryView<TKey, TInput, TOutput>> { [System.Runtime.CompilerServices.Nullable(new byte[] { 2, 1, 1 })] 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; } [return: System.Runtime.CompilerServices.Nullable(new byte[] { 1, 0, 1, 1 })] public IEnumerator<KeyValuePair<TKey, TOutput>> GetEnumerator() { if (this.source != null) { foreach (KeyValuePair<TKey, TInput> item in (IEnumerable<KeyValuePair<TKey, TInput>>)this.source) { item.Deconstruct(out TKey key, out TInput value); TKey key2 = key; TInput arg = value; yield return new KeyValuePair<TKey, TOutput>(key2, this.mapper(arg)); } } } 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] [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1, 1, 1 })] ref ReadOnlyDictionaryView<TKey, TInput, TOutput> other) { if (source == other.source) return mapper == other.mapper; return false; } public bool Equals([System.Runtime.CompilerServices.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(); } [System.Runtime.CompilerServices.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] [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1, 1, 1 })] ref ReadOnlyDictionaryView<TKey, TInput, TOutput> first, [In] [IsReadOnly] [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1, 1, 1 })] ref ReadOnlyDictionaryView<TKey, TInput, TOutput> second) { return first.Equals(ref second); } public static bool operator !=([In] [IsReadOnly] [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1, 1, 1 })] ref ReadOnlyDictionaryView<TKey, TInput, TOutput> first, [In] [IsReadOnly] [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1, 1, 1 })] ref ReadOnlyDictionaryView<TKey, TInput, TOutput> second) { return !first.Equals(ref second); } } }