How to convert a dictionary to ConcurrentDictionary?

I saw how to convert ConcurrentDictionary to a dictionary , but I have a dictionary and you want to convert to ConcurrentDictionary. How to do this? ... even better, can I set the link operator in ConcurrentDictionary?

var customers = _customerRepo.Query().Select().ToDictionary(x => x.id, x => x); 
+6
source share
4 answers

Using the ConcurrentDictionary<TKey, TValue> Constructor (IEnumerable<KeyValuePair<TKey, TValue>>) constructor that can accept a dictionary object, for example:

 Dictionary<int, string> dictionary = new Dictionary<int, string>(); dictionary.Add(1,"A"); dictionary.Add(2, "B"); ConcurrentDictionary<int,string> concurrentDictionary = new ConcurrentDictionary<int, string>(dictionary); 

Can I set the LINQ statement as ConcurrentDictionary?

No. You can not. . There is no extension method for creating a ConcurrentDictionary in LINQ. You can either create your own extension method or use the ConcurrentDictionary constructor in the LINQ query when projecting the results.

+14
source

Why not write your own extension method:

  public static class ConcurrentDictionaryExtensions { public static ConcurrentDictionary<TKey, TElement> ToConcurrentDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer) { if (source == null) throw new ArgumentNullException("source"); if (keySelector == null) throw new ArgumentNullException("keySelector"); if (elementSelector == null) throw new ArgumentNullException("elementSelector"); ConcurrentDictionary<TKey, TElement> d = new ConcurrentDictionary<TKey, TElement>(comparer); foreach (TSource element in source) d.TryAdd(keySelector(element), elementSelector(element)); return d; } public static ConcurrentDictionary<TKey, TSource> ToConcurrentDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) { return ToConcurrentDictionary<TSource, TKey, TSource>(source, keySelector, IdentityFunction<TSource>.Instance, null); } public static ConcurrentDictionary<TKey, TSource> ToConcurrentDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer) { return ToConcurrentDictionary<TSource, TKey, TSource>(source, keySelector, IdentityFunction<TSource>.Instance, comparer); } public static ConcurrentDictionary<TKey, TElement> ToConcurrentDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector) { return ToConcurrentDictionary<TSource, TKey, TElement>(source, keySelector, elementSelector, null); } internal class IdentityFunction<TElement> { public static Func<TElement, TElement> Instance { get { return x => x; } } } } 

Just accepted code from the .NET framework .

+4
source

The LINQ-To-Objects statement is ultimately IEnumerable, so you can pass it to the ConcurrentDictionary constructor, for example:

 var customers = myCustomers.Select(x => new KeyValuePair(x.id, x)); var dictionary=new ConcurrentDictionary(customers); 

This may not work with other suppliers. Linq to Entities, for example, converts the entire LINQ statement to SQL and cannot design on KeyValuePair. In this case, you may need to call AsEnumerable() or any other method that causes IQueryable to execute, for example:

 var customers = _customerRepo.Customers.Where(...) .AsEnumerable() .Select(x => new KeyValuePair(x.id, x)); var dictionary=new ConcurrentDictionary(customers); 

Select() without arguments is not IEnumerable or IQueryable, so I assume this is a method provided by some other ORM. If Select() returns an IEnumerable, you can use the first option, otherwise you can use AsEnumerable()

+2
source

Or just have have method:

  private ConcurrentDictionary<TKey, TValue> ToConcurrent<TKey, TValue>(Dictionary<TKey, TValue> dic) { return new ConcurrentDictionary<TKey, TValue>(dic); } 

and then do:

 var customers = _customerRepo.Query().Select().ToDictionary(x => x.id, x => x); var concurrentDic = ToConcurrent(customers); 

Personally, I am moving on to the extension method that I just updated ...

0
source

Source: https://habr.com/ru/post/978520/


All Articles