2013-06-26 34 views
5

Tôi đang cố gắng viết một phương pháp mở rộng sẽ chuyển đổi IDictionary<K, S<V>> giữ bất kỳ loại bộ sưu tập/chuỗi nào (S<V>) thành ILookup<K, V>. những trường hợp đó. Điều này có nghĩa tôi muốn mở rộng của tôi để làm việc trên S loại và các giao diện khác nhau:Phương pháp mở rộng đơn trên IDictionary <K, IEnumerable/IList/ICollection <V>>

  • IDictionary<K, IEnumerable<V>>
  • IDictionary<K, ICollection<V>>
  • IDictionary<K, List<V>>

vv Lý tưởng nhất, tôi không muốn viết riêng thực hiện cho từng loại bộ sưu tập có thể VÀ tôi muốn suy luận kiểu để thực hiện công việc của mình.

Những gì tôi đã cố gắng là:

public static ILookup<TKey, TValue>ToLookup<TKey, TCollection, TValue>(
    this IDictionary<TKey, TCollection> dictionary) 
     where TCollection : IEnumerable<TValue> 

Nhưng nó không có TValue trong danh sách các thông số, vì vậy gõ suy luận là không thể hình dung nó ra - tôi nhận được "Những lập luận kiểu cho phương pháp ToLookup không thể được suy ra từ việc sử dụng".

Có khả năng nó có thể hoạt động bằng cách nào đó khác hơn là thêm thông số giả mạo TValue giả mạo vào phương pháp?

Ví dụ về việc sử dụng dự kiến ​​

Tôi hy vọng tất cả trên cuộc gọi đến có thể và kết quả là một cuộc gọi đến phương pháp mở rộng duy nhất của tôi:

var dictOfIEnumerables = new Dictionary<int, IEnumerable<int>>(); 
var lookupFromIEnumerables = dictOfIEnumerables.ToLookup(); 

var dictOfICollections = new Dictionary<int, ICollection<int>>(); 
var lookupFromICollections = dictOfICollections.ToLookup(); 

var dictOfLists = new Dictionary<int, List<int>>(); 
var lookupFromLists = dictOfLists.ToLookup(); 
+0

Khi bạn sử dụng nó, hãy thử chỉ định rõ ràng các loại cho generics – Mgetz

+0

@Mgetz - Tôi nghĩ đó chính xác là những gì NOtherDev cố gắng tránh - hoặc chỉ rõ các kiểu rõ ràng hoặc có đối số giả để ép buộc loại. Mẫu của việc sử dụng dự kiến ​​có thể sẽ xóa mọi thứ. –

+0

Vâng, như tôi đã đề cập, tôi muốn suy luận kiểu để thực hiện công việc của mình. Sẽ thêm các ví dụ sử dụng dự kiến ​​vào câu hỏi. – NOtherDev

Trả lời

1

Vì tất cả các bộ sưu tập thực hiện IEnumerable<T>, chúng tôi chỉ có thể sử dụng nó thay vì thông số loại TCollection. Thật không may là suy luận kiểu không biết điều này.Đây là mã tôi đã viết:

public static ILookup<TKey, TValue> ToLookup<TKey, TValue> 
     (this IDictionary<TKey, IEnumerable<TValue>> dict) 
{ 
    return dict.SelectMany(p => p.Value.Select 
     (v => new KeyValuePair<TKey, TValue>(p.Key, v))) 
     .ToLookup(p => p.Key, p => p.Value); 
} 

Có vẻ là không có cách nào làm cho việc suy luận kiểu, nhưng phương pháp này sẽ có tác dụng nếu bạn cast Từ điển:

((IDictionary<int, IEnumerable<int>>)dictOfLists).ToLookup() 

Ngoài ra bạn có thể thêm Lists vào một từ điển của IEnumerables và đưa chúng trở lại khi bạn cần chúng.

0

Từ chút thử nghiệm tôi đã thực hiện, đây là kết quả của tôi.

Nếu tôi nhập dictOfIEnumerables.ToLookup(, tôi thấy 4 phương thức quá tải.
enter image description here

Tuy nhiên, nếu tôi nhập dictOfIEnumerables.ToLookup<, tôi thấy tất cả 5 phương pháp quá tải. enter image description here

Dường như suy luận kiểu không hoạt động, vì va chạm tên/xung đột độ phân giải giữa ToLookup() được xác định trên IEnumerable. Rõ ràng, không có các dấu ngoặc nhọn, nó sẽ giải quyết các phương thức được định nghĩa trên IEnumerable, vì đó là những gì TCollection bị hạn chế. Có thể ai đó trên StackOverflow thông minh hơn tôi có thể giải thích cho bạn tại sao nó hoạt động theo cách của nó.

Tuy nhiên, việc sử dụng các loại được chỉ định thực tế, hoạt động chính xác trên máy của tôi. enter image description here

+0

Vâng, thực sự vấn đề không phải do va chạm tên, vấn đề vẫn tồn tại với 'ToLookup2'. Tôi biết tôi có thể chỉ định các đối số một cách rõ ràng, nhưng đó chính xác là những gì tôi đang cố gắng tránh. Có vẻ như tôi cần phải sao chép phương thức cho mỗi giao diện ... – NOtherDev

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