Returns a new dictionary from the source IEnumerable
using the provided keySelector function to determine keys. Will throw an ArgumentException
if keySelector is not injective(returns a unique value for each member of the source collection.) There are overloads which allow one to specify the value to be stored as well as the key.
var persons = new[] {
new { Name="Fizz", Id=1},
new { Name="Buzz", Id=2},
new { Name="Foo", Id=3},
new { Name="Bar", Id=4},
};
Specifying just a key selector function will create a Dictionary<TKey,TVal>
with TKey
the return Type of the key selector, TVal
the original object Type, and the original object as the stored value.
var personsById = persons.ToDictionary(p => p.Id);
// personsById is a Dictionary<int,object>
Console.WriteLine(personsById[1].Name); //Fizz
Console.WriteLine(personsById[2].Name); //Buzz
Specifying a value selector function as well will create a Dictionary<TKey,TVal>
with TKey
still the return type of the key selector, but TVal
now the return type of the value selector function, and the returned value as the stored value.
var namesById = persons.ToDictionary(p => p.Id, p => p.Name);
//namesById is a Dictionary<int,string>
Console.WriteLine(namesById[3]); //Foo
Console.WriteLine(namesById[4]); //Bar
As stated above, the keys returned by the key selector must be unique. The following will throw an exception.
var persons = new[] {
new { Name="Fizz", Id=1},
new { Name="Buzz", Id=2},
new { Name="Foo", Id=3},
new { Name="Bar", Id=4},
new { Name="Oops", Id=4}
};
var willThrowException = persons.ToDictionary(p => p.Id)
If a unique key can not be given for the source collection, consider using ToLookup instead. On the surface, ToLookup behaves similarly to ToDictionary, however, in the resulting Lookup each key is paired with a collection of values with matching keys.