使用linq或IEnumerable将数组转换为并发字典的更好方法是什么?

Nik*_*hil 7 c# linq lambda extension-methods

我有一个ArrayPerson对象,我想将其转换为一个ConcurrentDictionary.存在用于将Arraya 转换为a的扩展方法Dictionary.是否有任何扩展方法将转换ArrayConcurrentDictionary

public class Person
{
    public Person(string name, int age)
    {
        Name =name;
        Age = age;
    }

    public string Name { get; set; }
    public int Age { get; set; }
}

Dictionary<int, Person> PersonDictionary = new Dictionary<int, Person>(); 
Person[] PersonArray = new Person[]
{
    new Person("AAA", 30),
    new Person("BBB", 25),
    new Person("CCC",2),
    new Person("DDD", 1)
};

PersonDictionary = PersonArray.ToDictionary(person => person.Age);
Run Code Online (Sandbox Code Playgroud)

用于将Arraya 转换为ConcurrentDictionary?的任何类似的扩展方法/ lambda表达式

Ada*_*dam 18

当然,使用接受以下内容的构造函数IEnumerable<KeyValuePair<int,Person>>:

var personDictionary = new ConcurrentDictionary<int, Person>
                       (PersonArray.ToDictionary(person => person.Age));
Run Code Online (Sandbox Code Playgroud)

var推断出类型ConcurrentDictionary<int,Person>.

如果您要创建一个扩展方法,正如Wasp建议的那样,我建议使用以下版本,它提供了一些更流畅的语法:

public static ConcurrentDictionary<TKey, TValue> ToConcurrentDictionary<TKey, TValue> 
(this IEnumerable<TValue> source, Func<TValue, TKey> valueSelector)
{
    return new ConcurrentDictionary<TKey, TValue>
               (source.ToDictionary(valueSelector));
}
Run Code Online (Sandbox Code Playgroud)

用法类似于ToDictionary,创造一致的感觉:

var dict = PersonArray.ToConcurrentDictionary(person => person.Age);
Run Code Online (Sandbox Code Playgroud)

  • 虽然这个答案是有效的,但[Wasp的答案](http://stackoverflow.com/a/12396386/1149773)在计算和内存需求方面更胜一筹.这个答案要求构造`Dictionary <TKey,TElement>`,只是立即丢弃. (2认同)

Was*_*asp 12

您可以非常轻松地编写自己的扩展方法,例如:

public static class DictionaryExtensions
{
    public static ConcurrentDictionary<TKey, TValue> ToConcurrentDictionary<TKey, TValue>(
        this IEnumerable<KeyValuePair<TKey, TValue>> source)
    {
        return new ConcurrentDictionary<TKey, TValue>(source);
    }

    public static ConcurrentDictionary<TKey, TValue> ToConcurrentDictionary<TKey, TValue>(
        this IEnumerable<TValue> source, Func<TValue, TKey> keySelector)
    {
        return new ConcurrentDictionary<TKey, TValue>(
            from v in source 
            select new KeyValuePair<TKey, TValue>(keySelector(v), v));
    }

    public static ConcurrentDictionary<TKey, TElement> ToConcurrentDictionary<TKey, TValue, TElement>(
        this IEnumerable<TValue> source, Func<TValue, TKey> keySelector, Func<TValue, TElement> elementSelector)
    {            
        return new ConcurrentDictionary<TKey, TElement>(
            from v in source
            select new KeyValuePair<TKey, TElement>(keySelector(v), elementSelector(v)));
    }
}
Run Code Online (Sandbox Code Playgroud)