Ответ 1
Вам нужно указать значения для Dictionary
var d2 = q.ToDictionary(p => p.NickName, p => p.Name);
public class Person
{
public string NickName{ get; set; }
public string Name{ get; set; }
}
var pl = new List<Person>;
var q = from p in pl
where p.Name.First() == 'A'
orderby p.NickName
select new KeyValuePair<String, String>(p.NickName, p.Name);
var d1 = q.ToList(); // Gives List<KeyValuePair<string, string>>
var d2 = q.ToDictionary(); // Does not compile
Как получить словарь < string, string > ?
Вам нужно указать значения для Dictionary
var d2 = q.ToDictionary(p => p.NickName, p => p.Name);
Словарь не может содержать несколько одинаковых ключей, поэтому вы должны убедиться (или знать), что это не так. Вы можете использовать GroupBy
, чтобы убедиться в этом:
Dictionary<string, string> dict = pl
.Where(p => p.Name.First() == 'A')
.GroupBy(p => p.NickName)
.ToDictionary(g => g.Key, g => g.First().Name);
ИЗМЕНИТЬ
Если вы действительно чувствуете, что вам нужно получить от IEnumerable<KeyValuePair<TKey, TValue>>
до Dictionary
неявно, вы можете добавить это расширение.
public static IDictionary<TKey, ToValue> ToDictionary<TKey, TValue>(
this IEnumerable<KeyValuePair<TKey, TValue>> source)
{
return source.ToDictionary(p => p.Key, p => p.Value);
}
Затем вы можете вызвать ToDictionary()
на любом IEnumerable<KeyValuePair<TKey, TValue>>
.
РЕДАКТИРОВАТЬ 2
Если вы ожидаете дублирования, вы также можете создать расширение ToLookup()
.
public static ILookup<TKey, TValue> ToLookup<TKey, TValue>(
this IEnumerable<KeyValuePair<TKey, TValue>> source)
{
return source.ToLookup(p => p.Key, p => p.Value);
}
В качестве альтернативы, если вы действительно хотите отменить результаты, вы можете добавить перегрузку для ToDictionary
.
public static IDictionary<TKey, ToValue> ToDictionary<TKey, TValue>(
this IEnumerable<KeyValuePair<TKey, TValue>> source,
Func<<IEnumerable<TValue>, TValue> selector)
{
return source
.Lookup(p => p.Key, p => p.Value);
.ToDictionary(l => l.Key, l => selector(l));
}
Если вы произвольно отбросьте все, кроме "первого" (что означает это без элемента OrderBy
), вы можете использовать это расширение следующим образом:
pairs.ToDictionary(v => v.First());
В целом вы можете удалить большую часть своего кода и сделать,
var q = from p in pl
where p.Name.First() == 'A';
var d = q.ToDictionary(p => p.NickName, p => p.Name);
Если могут быть дубликаты, do
var d = q.ToLookup(p => p.NickName, p => p.Name);
но заметьте, это возвращает ILookup<TKey, TElement>
, Item
указатель которого возвращает IEnumerable<TElement>
, поэтому вы не отбрасываете данные.
Попробуйте использовать NickName в качестве ключа и имя как значение
var d2 = q.ToDictionary (p => p.NickName, p=>p.Name);
Но обратите внимание, что словарь не позволяет дублировать, поэтому выше будет вызывать ошибку для дубликатов записей с одним и тем же псевдонимом. Возможно, вы хотели бы использовать Lookup, который похож на словарь, но позволяет дублировать
var d2 = q.ToLookup (p => p.NickName, p=>p.Name);
Я понимаю, что это было помечено С#, но Я был буквально просто, пытаясь понять, как это сделать в vb.net вчера, поэтому я подумал, что поделился бы тем, как вы это сделаете и в VB:
Public Class Person
Property NickName As String
Property Name As String
End Class
Sub Main()
Dim p1 As New List(Of Person)
'*** Fill the list here ***
Dim q = (From p In p1
Where p.Name.First = "A"
Select p.NickName, p.Name).ToDictionary(
Function(k) k.NickName,
Function(v) v.Name)
End Sub