2010-11-22 162 views
6

鑑於以下代碼,我無法返回字典。ToDictionary不按預期工作

[JsonProperty] 
public virtual IDictionary<Product, int> JsonProducts 
{ 
    get 
    { 
     return Products.ToDictionary<Product, int>(x => x.Key, v => v.Value); 
    } 
} 

public virtual IDictionary<Product, int> Products { get; set; } 

我收到以下錯誤..

「System.Collections.Generic.IDictionary」不包含「ToDictionary」和最佳推廣方法重載「的定義System.Linq.Enumerable .ToDictionary(System.Collections.Generic.IEnumerable,System.Func,System.Collections.Generic.IEqualityComparer)」具有一些無效參數

不能從轉換的lambda表達式'到 'System.Func'

無法從'lambda表達式'轉換爲'System.Collections.Generic.IEqualityComparer

沒有什麼特別的產品類。它被簡單地定義爲

class Product 
{ 
    public virtual int Id { get; set; } 
    public virtual String Name { get; set; } 
} 
+0

@Brad Christie:`IDictionary `implements`IEnumerable >`並且有一個擴展方法`IEnumerable >。ToDictionary`在靜態類Enumerable中定義。 – jason 2010-11-22 15:54:31

回答

10

爲什麼使用

Products.ToDictionary<Product, int>(x => x.Key, v => v.Value) 

,而不是僅僅

Products.ToDictionary(x => x.Key, v => v.Value) 


這是因爲

public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(
    this IEnumerable<TSource> source, 
    Func<TSource, TKey> keySelector, 
    Func<TSource, TElement> elementSelector 
); 

看看到的泛型類型參數(Func鍵)的數量(3)和類型。

,這意味着你需要調用它:

Products.ToDictionary<KeyValuePair<Product, int>, Product, int>(x => x.Key, v => v.Value); 
+1

方法'ToDictionary'沒有重載需要0個參數 – Ciel 2010-11-22 15:53:08

1

沒有明確指定的泛型類型參數。 ToDictionary<T1, T2>中的類型不是T1 = TKeyT2 = TValue(其中TKey是生成字典的鍵的類型,而TValue是字典中結果值的類型)。

接受兩個通用類型參數的ToDictionary的超負荷具有T = TSourceV = TKey。在這裏,TSource = KeyValuePair<Product, int>。此外,您正在調用具有兩個參數的overload of ToDictionary。第一個參數是來自T1 -> T2的地圖,第二個參數是IEqualityComparer<T2>。但是x => x.Key不是從KeyValuePair<Product, int>intv => v.Value不是IEqualityComparer<int>的地圖。

如果不明確指定泛型類型參數,編譯器將檢查x => x.Keyv => v.Value的類型,並查看ToDictionary的各種超載。有四個

  1. ToDictionary<TSource, TKey>(IEnumerable<TSource>, Func<TSource, TKey>)
  2. ToDictionary<TSource, TKey>(IEnumerable<TSource>, Func<TSource, TKey>, IEqualityComparer<TKey>)
  3. ToDictionary<TSource, TKey, TElement>(IEnumerable<TSource>, Func<TSource, TKey>, Func<TSource, TElement>)
  4. ToDictionary<TSource, TKey, TElement>(IEnumerable<TSource>, Func<TSource, TKey>, Func<TSource, TElement>, IEqualityComparer<TKey>)

注意,它可以立即排除1和4,因爲他們有錯誤的參數數量(2和4,而你正在調用一個需要三個參數的重載(第三個是隱藏的第一個參數,因爲你正在調用一個extensi on方法))。它可以排除2.因爲對於任何T,最後一個參數不能轉換爲IEqualityComparer<T>。這留下了最後的重載。它是能夠推導出x => x.KeyFunc<KeyValuePair<Product, int>, Product>,即v => v.ValueFunc<KeyValuePair<Product, int>, int>,因此,您正在調用

ToDictionary<KeyValuePair<Product, int>, Product, int>(
    IEnumerable<KeyValuePair<Product, int>>, 
    Func<KeyValuePair<Product, int>, Product>, 
    Func<KeyValuePair<Product, int>, int> 
) 

如果你想明確地指定類型參數,你不得不說

Products.ToDictionary<KeyValuePair<Product, int>, Product, int>(
    x => x.Key, 
    v => v.Value 
); 
0

如果你實際上並沒有克隆產品實例,你可以這樣做:

public virtual IDictionary<Product, int> JsonProducts 
{ 
    get 
    { 
     return new Dictionary(Products); 
    } 
}