2013-06-11 33 views
7

Tôi đã một cuốn từ điển định nghĩa là Dictionary<string, int> onechuyển đổi từ var vào từ điển <String,int>

nó có một số dữ liệu và tôi làm LINQ sau vào nó

var temp = one.OrderBy(r => r.Value).Select(r => r.Key).Take(5);

Nhưng bây giờ tôi muốn chuyển đổi nó trở lại vào một từ điển `Dictionary

Tôi đã thử sử dụng temp.ToDictionary(r => r.Key, r => r.Value);

Nhưng nó cho tôi biết: Không thể chuyển đổi biểu thức lambda thành kiểu 'System.Collections.Generic.IEqualityComparer' vì nó không phải là loại đại biểu

Làm cách nào để thực hiện chuyển đổi này?

Trả lời

14

Đó là vì bạn vứt bỏ Value bằng cuộc gọi đến Select(r => r.Key). Bạn sẽ cần giữ lại KeyValuePair với nhau nếu bạn muốn chuyển đổi nó trở lại từ điển.

var temp = one.OrderBy(r => r.Value).Take(5); 

var backToDictionary = temp.ToDictionary(r => r.Key, r => r.Value); 

Nếu bạn vẫn muốn có một IEnumerable<string> trong những chìa khóa như trong câu hỏi của bạn, bạn có thể sử dụng riêng rẽ:

var tempKeys = temp.Select(r => r.Key); 

Lý do bạn nhận được một thông báo lỗi dường như không liên quan đề cập đến một IEqualityComparer là bởi vì trình biên dịch đang cố gắng để thực hiện một dự đoán tốt nhất là quá tải mà bạn đang cố gắng gọi. Dự đoán tốt nhất của nó trong trường hợp này là nghĩ rằng bạn đang cố gắng gọi this overload.

xem xét mã bạn có và loại nó sản xuất:

IEnumerable<string> temp = one.OrderBy(r => r.Value).Select(r => r.Key).Take(5); 

này sẽ tạo ra một đối tượng thực hiện IEnumerable<string>. Sau đó, với cuộc gọi của bạn về:

temp.ToDictionary(r => r.Key, r => r.Value); 

r trong trường hợp này là string. Trình biên dịch tại thời điểm này là freaking ra bởi vì không có những điều như r.Key cũng không r.Value. Nó nhận ra rằng có 2 tham số đang được sử dụng, và do đó có hai tình trạng quá tải có thể chọn từ ToDictionary (this methodthis one). Tại thời điểm này, tôi không chắc chắn những gì các quy tắc được cho trình biên dịch để chọn một trong khác (đặc biệt là vì nó không thể suy ra các loại r.Key hoặc r.Value), nhưng nó đã chọn một trong số họ. (có lẽ nó chỉ đơn giản là "đầu tiên" một tuyên bố/tìm thấy? Có lẽ nó ủng hộ đầu vào đối tượng trực tiếp trên biểu thức lambda?) Ở mức nào, nó chọn quá tải yêu cầu IEqualityComparer thay vì một Func<TSource, TElement> và nói với bạn (tự nhiên) rằng một biểu thức lambda là không thể chuyển đổi thành IEqualityComprarer.

Theo kinh nghiệm của tôi, khi bạn nạp rác cho trình biên dịch (r.Keyr.Value trong trường hợp này), độ phân giải quá tải sẽ biến mất ngoài cửa sổ. Đôi khi nó hoạt động, thường là khi chỉ có một quá tải phù hợp với thông số số hoặc ít nhất không có sự mơ hồ.Nhưng lần khác bạn chỉ cần xem qua lỗi trình biên dịch và khắc phục vấn đề gốc.

+0

Tại sao lỗi nói về 'IEqualityComparer'? Không nên trình biên dịch chỉ có thể phát hiện rằng 'Key' và' Giá trị' không được định nghĩa trong 'chuỗi'? – voithos

+0

@voithos Rất có thể trình biên dịch đang cố gắng thực hiện "phỏng đoán tốt nhất" về mức độ bạn đang cố gắng gọi. Tôi sẽ cập nhật câu trả lời của mình. –

+0

@voithos Tôi đã thêm giải thích chi tiết về lý do lỗi cụ thể đó xuất hiện. –

Các vấn đề liên quan