2013-06-26 18 views
5

I toplama/dizisinin herhangi bir tür tutma IDictionary<K, S<V>> dönüştürür bir uzantısı yöntem yazmak çalışıyorum (S<V>) daha uygun veri yapısı olan ILookup<K, V> için bu davalar. İdeal olarak, ben ayrı yazmak istemiyorum vbtek uzantı metodu <K, IEnumerable/IList/ıcollection <V>>

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

  • IDictionary<K, ICollection<V>>
  • : Bu farklı S türleri ve arayüzleri üzerinde çalışmak benim uzantısı istiyorum demektir Mümkün olan her bir koleksiyon tipi için uygulama VE Ben işini yapmak için sonuç çıkarsama istiyorum.

    Ne denedim geçerli:

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

    Ama parametreler listesinde hiçbir TValue var, bu yüzden çıkarım yazın onu anlamaya edemiyor - Ben yöntem ToLookup için tür argümanlar anlaşılmaktadır edilemez" olsun kullanım".

    Bir şekilde, yöntemle sahte TValue -tipi parametresi eklemekten başka bir şekilde çalışabilme şansı var mı? beklenen kullanım

    Örnekler I her şeyden umut

    mümkün ve benim tek uzatma yöntemi çağrısı sonuçlanması çağırır: Yaptığım test bitten

    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

    Bunu kullandığınızda, yalnızca jenerikler için türleri açıkça belirtmeyi deneyin. – Mgetz

    +0

    @Mgetz - Bence, tamamen açık tipler belirtmek veya türleri zorlamak için sahte argümanlar kullanmaktan kaçınılamaya çalışıyorum. Beklenen kullanımın örneği muhtemelen bazı şeyleri temizleyecektir. –

    +0

    Evet, bahsettiğim gibi, işini yapmak için çıkarımda bulunmak istiyorum. Soruya beklenen kullanım örneklerini ekleyecektir. – NOtherDev

    cevap

    1

    , sadece TCollection tip Paramtre yerine kullanabilirsiniz. Ne yazık ki tür çıkarımı bunu bilmiyor.Bu yazdığım kodudur:

    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); 
    } 
    

    tür kesmesi işi yapmanın hiçbir yolu gibi görünüyor, ancak Sözlüğü döküm eğer bu yöntem çalışır: Ayrıca Listeleri ekleyebilir

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

    Bir IEnumerables Sözlüğüne ve ihtiyacınız olduğunda onları geri çevirir.

    0

    , İşte benim sonuçlarım.

    dictOfIEnumerables.ToLookup( yazıyorsam, aşırı yüklü 4 yöntem görüyorum. Ben dictOfIEnumerables.ToLookup< yazarsanız
    enter image description here

    Ancak, ben 5 aşırı yöntemleri görüyoruz. enter image description here

    O tür kesmesi nedeniyle IEnumerable tanımlanır ToLookup (arasındaki isim çarpışma/çözünürlük çarpışma) arasında, çalışmıyor görünür. Görünüşe göre, açılı ayraçlar olmadan, IEnumerable'da tanımlanan yöntemlere çözüm getiriyor, çünkü bu TCollection'ın kısıtladığı şeydir. Belki StackOverflow'taki birinden daha akıllı, neden böyle çalıştığını size açıklayabilir. Bununla birlikte, belirtilen türlerin kullanılması aslında makinemde doğru şekilde çalışıyor demektir. Tüm koleksiyonları IEnumerable<T> uygulamak Çünkü enter image description here

    +0

    Aslında, aslında isim çarpışma nedeniyle değil, sorun 'ToLookup2' ile devam ediyor. Açıkça argümanları belirleyebileceğimi biliyorum, ama aynen kaçınmaya çalışıyorum. Her arabirim için yöntemi kopyalamakla gitmem gerekiyormuş gibi görünüyor. – NOtherDev

    İlgili konular