如何将字典转换为ConcurrentDictionary?

时间:2014-11-21 14:43:05

标签: c# asp.net .net dictionary concurrentdictionary

我已经看过如何转换ConcurrentDictionary to a Dictionary,但我有一个字典,想转换为ConcurrentDictionary。我该怎么做?...更好的是,我可以将link语句设置为ConcurrentDictionary吗?

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

4 个答案:

答案 0 :(得分:17)

使用 ConcurrentDictionary<TKey, TValue> Constructor (IEnumerable<KeyValuePair<TKey, TValue>>) constructor可以接受字典对象,如:

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);
  

我可以将 LINQ 语句设置为ConcurrentDictionary吗?

没有。 你不能。。在LINQ中没有可用于创建ConcurrentDictionary的扩展方法。您可以创建自己的扩展方法,也可以在投影结果时在LINQ查询中使用ConcurrentDictionary构造函数。

答案 1 :(得分:4)

为什么不编写自己的扩展方法:

  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; }
        }
    }

}

只需采用.Net framework

中的代码

答案 2 :(得分:2)

LINQ-To-Objects语句最终是一个IEnumerable,因此您可以将它传递给ConcurrentDictionary构造函数,例如:

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

这可能不适用于其他提供商。例如,Linq to Entities将整个LINQ语句转换为SQL,无法投影到KeyValuePair。在这种情况下,您可能必须调用AsEnumerable()或强制IQueryable执行的任何其他方法,例如:

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

Select()不是IEnumerable或IQueryable方法,所以我认为它是一些其他ORM提供的方法。如果Select()返回IEnumerable,您可以使用第一个选项,否则您可以使用AsEnumerable()

答案 3 :(得分:0)

或者只是一个方法:

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

然后执行:

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

就个人而言,我正在使用我刚刚更新的扩展方法......