ToDictionary无法按预期工作

时间:2010-11-22 15:45:59

标签: c# linq

鉴于以下代码,我无法返回字典。

[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 expression'转换为'System.Func'

     

无法从'lambda expression'转换为'System.Collections.Generic.IEqualityComparer

Product类没有什么特别之处。它只是定义为

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

3 个答案:

答案 0 :(得分: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
);

查看数字(3)和泛型类型参数(Func)的类型。

这意味着您需要调用它:

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

答案 1 :(得分: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>int的地图,v => 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>)
  5. 请注意,它可以立即排除1.和4.因为它们具有错误的参数数量(分别为2和4,而您正在调用需要三个参数的重载(第三个是隐藏的第一个参数,因为您正在调用扩展方法))。它可以排除2.因为对于任何IEqualityComparer<T>,最后一个参数都无法转换为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
    );
    

答案 2 :(得分:0)

如果您实际上没有克隆产品实例,则可以执行以下操作:

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