2010-11-22 164 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); 
    } 
}