IEnumerable使用提供的keySelector函数从源返回一个新字典来确定键。ArgumentException如果keySelector不是注入式的,将抛出一个if(不是,它为源集合的每个成员返回一个唯一的值。)有重载,允许人们指定要存储的值以及键。
var persons = new[] { new { Name="Fizz", Id=1}, new { Name="Buzz", Id=2}, new { Name="Foo", Id=3}, new { Name="Bar", Id=4}, };
仅指定一个键选择器函数将创建一个Dictionary<TKey,TVal>带有键选择器TKey的返回类型,TVal原始对象类型和原始对象作为存储值的。
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
同时指定一个值选择器函数将创建一个仍Dictionary<TKey,TVal>带有TKey键选择器TVal的返回类型,但是现在是值选择器函数的返回类型,并以返回值作为存储值的。
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
如上所述,键选择器返回的键必须唯一。以下将引发异常。
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)
如果无法为源集合提供唯一键,请考虑改为使用ToLookup。从表面上看,ToLookup的行为与ToDictionary相似,但是,在生成的Lookup中,每个键都与具有匹配键的值的集合配对。