2010-03-29 34 views
12

Tôi đang sử dụng một số Dictionary<int, MyType> trong một lớp học. Lớp đó triển khai một giao diện yêu cầu trả về IList<MyType>. Có cách nào đơn giản để đúc cái này sang cái kia (không sao chép toàn bộ nội dung)?Chuyển đổi từ điển <MyType> .ValueCollection to IList <MyType>

giải pháp hiện tại của tôi sau:

private IList<MyType> ConvertToList(Dictionary<int, MyType>.ValueCollection valueCollection) 
{ 
    List<MyType> list = new List<MyType>(); 
    list.AddRange(valueCollection); 
    return list; 
} 
+0

Mọi giải pháp được đăng cho đến nay liên quan đến việc sao chép toàn bộ bộ sưu tập. **Đọc câu hỏi**. – SLaks

+0

@SLaks: Tôi đã giải quyết trực tiếp câu trả lời của tôi ... (vẫn liên quan đến việc sao chép) –

+0

Có bất kỳ sự liên quan nào đối với keyType "int" hay là loại tùy ý không? –

Trả lời

20

Bạn sẽ cần phải làm một bản sao, nhưng điều này có lẽ là một điều tốt. Trong C# 2, mã hiện tại của bạn gần như là sạch nhất mà bạn có thể thực hiện. Nó sẽ được cải thiện bằng cách trực tiếp xây dựng danh sách của bạn giảm giá trị của bạn (List<MyType> list = new List<MyType>(valueCollection);), nhưng vẫn cần một bản sao.

Sử dụng LINQ với C# 3, tuy nhiên, bạn sẽ có thể làm:

myDictionary.Values.ToList(); 

Điều đó đang được nói, tôi sẽ không (có lẽ) cố gắng tránh các bản sao. Việc trả lại bản sao các giá trị của bạn có xu hướng an toàn hơn vì nó ngăn người gọi gây ra sự cố nếu họ cố sửa đổi bộ sưu tập của bạn. Bằng cách trả lại một bản sao, người gọi có thể làm list.Add(...) hoặc list.Remove(...) mà không gây ra sự cố về lớp học của bạn.


Edit: Với nhận xét của bạn dưới đây, nếu tất cả các bạn muốn là một IEnumerable<T> với Count, bạn chỉ có thể trở lại ICollection<T>. này được thực hiện trực tiếp bởi ValueCollection, có nghĩa là bạn chỉ có thể trả về giá trị của từ điển của bạn trực tiếp, không có sao chép:

private ICollection<MyType> ConvertToList(Dictionary<int, MyType>.ValueCollection valueCollection) 
{ 
    return valueCollection; 
} 

(Cấp, phương pháp này trở nên thực sự vô dụng trong trường hợp này - nhưng tôi muốn chứng tỏ nó cho bạn ...)

+0

@ Slaks: Do đó câu tiếp theo: "Bạn có thể trực tiếp xây dựng danh sách của bạn khỏi giá trị của bạn,";) Đó không phải là tốt hơn nhiều, mặc dù vì nó là một ICollection , nó sẽ hiệu quả hơn (vì đếm được biết trước). –

+0

@Slaks: Tốt hơn? Tôi đã làm cho nó rõ ràng hơn. –

+0

Cảm ơn câu trả lời tuyệt vời. Giao diện ICollection phù hợp với nhu cầu của tôi một cách hoàn hảo. –

0

Bạn có thể sử dụng các nhà xây dựng: (. Edited để loại bỏ một khẳng định tôi không phải là chắc chắn 100% trên)

public IList<MyType> MyValues 
{ 
    get { return new List<MyType>(myDictionary.Values); } 
} 

+0

Điều này vẫn tạo bản sao của bộ sưu tập. – mcNux

4

thế nào về

Dictionary<int, MyType> dlist = new Dictionary<int, MyType>(); 
IList<MyType> list = new List<MyType>(dlist.Values); 
+2

Điều này vẫn sao chép bộ sưu tập. – SLaks

2

Điều này là không thể.

Từ điển (bao gồm bộ sưu tập Values) là một bộ sưu tập vốn không có thứ tự; thứ tự của nó sẽ thay đổi dựa trên mã băm của khóa của nó. Đây là lý do tại sao ValueCollection không triển khai IList<T> ngay từ đầu.

Nếu bạn thực sự muốn, bạn có thể làm cho một lớp wrapper mà thực hiện IList và kết thúc tốt đẹp ValueCollection, sử dụng một vòng lặp foreach trong indexer. Tuy nhiên, nó không phải là một ý tưởng tốt.

+0

@SLaks Tôi không cầu kỳ về thứ tự. Những gì tôi muốn là IEnumerable với một số. Nếu có Giao diện tốt hơn, hãy cho tôi biết. –

+0

@C. Ross: Xem chỉnh sửa của tôi, sau đó ... –

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