/// <summary> /// Creates a <see cref="FrozenDictionary{TKey, TValue}"/> from an <see cref="IEnumerable{T}"/> according to specified key selector and value selector functions. /// </summary> /// <typeparam name="TSource"></typeparam> /// <param name="source"></param> /// <param name="keySelector"></param> /// <param name="valueSelector"></param> /// <returns></returns> public static FrozenDictionary <TKey, TValue> Create <TSource>(IEnumerable <TSource> source, Func <TSource, TKey> keySelector, Func <TSource, TValue> valueSelector) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (keySelector == null) { throw new ArgumentNullException(nameof(keySelector)); } if (valueSelector == null) { throw new ArgumentNullException(nameof(valueSelector)); } const int initialSize = 4; const float loadFactor = 0.75f; var size = source.CountIfMaterialized() ?? initialSize; var bucketSize = CalculateCapacity(size, loadFactor); var result = new FrozenDictionary <TKey, TValue>(bucketSize, loadFactor); foreach (var x in source) { var key = keySelector(x); var value = valueSelector(x); if (!result.TryAddInternal(key, value, out _)) { throw new ArgumentException($"Key was already exists. Key:{key}"); } } return(result); }
/// <summary> /// Converts to <see cref="FrozenDictionary{TKey, TValue}"/>. /// </summary> /// <typeparam name="TKey"></typeparam> /// <typeparam name="TValue"></typeparam> /// <param name="source"></param> /// <param name="keySelector"></param> /// <param name="valueSelector"></param> /// <returns></returns> public static FrozenDictionary <TKey, TValue> ToFrozenDictionary <TSource, TKey, TValue>(this IEnumerable <TSource> source, Func <TSource, TKey> keySelector, Func <TSource, TValue> valueSelector) => FrozenDictionary <TKey, TValue> .Create(source, keySelector, valueSelector);