2014-12-04 68 views
4

这工作:如何返回字典<int, object>?

public IDictionary<int, object> GetProducts(int departmentID) 
{ 
    return new Dictionary<int, object> 
       { 
        { 1, new { Description = "Something" } }, 
        { 2, new { Description = "Whatever" } }, 
       }; 
} 

但出于某种原因,这并不:

public IDictionary<int, object> GetProducts(int departmentID) 
{ 
    var products = ProductRepository.FindAll(p => p.Department.Id == departmentID); 

    return products.ToDictionary(p => p.Id, p => new { Description = p.Description }); 
} 

这不起作用或者:

public IDictionary<int, object> GetProducts(int departmentID) 
{ 
    var products = ProductRepository.FindAll(p => p.Department.Id == departmentID); 

    return products.ToDictionary(p => p.Id, p => new { p.Description }); 
} 

编译器错误(在两种情况下)是:

Cannot convert expression type 'System.Collections.Generic.Dictionary<int,{Description:string}>' to return type 'System.Collections.Generic.IDictionary<int,object>' 

我以为这是与ToDictionary LINQ的扩展方法的问题,但根据this answer应该因为工作的FindAll返回IQueryable<Product>

...如果你的数据从一个IEnumerable或IQueryable的源来了,你可以使用LINQ ToDictionary运营商出突起从序列元素所需的关键的 和(匿名类型)值 得到一个:

var intToAnon = sourceSequence.ToDictionary(
    e => e.Id, 
    e => new { e.Column, e.Localized }); 

是怎么回事?

+2

要知道,你就得值转换为比对象做任何有用的事情其他东西。由于实际值是匿名类型,因此您需要使用反射或“动态”,这两者都不是编译时安全的。你最好创建一个具体的类并使用_that_作为结果值类型。 – 2014-12-04 18:23:29

+0

那么,返回值被序列化为JSON,这非常有用。仅仅为了序列化JSON而创建模型对我来说似乎是多余的。 – 2014-12-04 18:29:39

+0

正确 - 这是一个有效的用法。 – 2014-12-04 18:30:41

回答

6

如何将字典值明确地转换为object

return products.ToDictionary(p => p.Id, p => (object)new { Description = p.Description }) 

其实,一个匿名对象是一个编译时随机创建的常规类的实例,因此它是一个对象,但它的一些特殊的类型。这就是为什么你不能期望隐式转换为IDictionary<string, object>

也许如果IDictionary<TKey, TValue>将支持covariantTValue ...

+0

你能澄清你的协变评论吗?我不确定这将如何解决问题。 – 2014-12-04 18:22:57

+0

@DStanley这就是为什么我说“如果它会......”,我还没有进入关于它是否可能的讨论...... – 2014-12-04 18:38:21

+0

@DStanley我已经修改了最后一句:D – 2014-12-04 19:58:01

3

这是一个不好的做法与匿名类型像你这样的工作。不要试图将它们包装成object。如果您需要匿名类型,请在您定义它们的相同方法环境中使用它们。

什么只是改变你的方法:

public IDictionary<int, object> GetProducts(int departmentID) 
{ 
    return new Dictionary<int, object> 
       { 
        { 1, "Something"}, 
        { 2, "Whatever"}, 
       }; 
} 

再投对象转换回字符串?

当然,这是假设你不能只是改变类型IDictionary<int, string>

+0

该值实际上需要几个属性(不仅仅是描述),例如价格,名称,颜色等。我只在示例中包含一个属性以简化它。为什么这是不好的做法? – 2014-12-04 18:19:52

+1

@Koveras,因为你不能将对象转换回匿名类型。你将被迫使用'动态'或反射来获取属性。创建类来放置你的值通常会更好。 – juharr 2014-12-04 18:28:33

+0

@Koveras在你的情况下,创建一个额外的Product类来保存数据也是合理的 – 2014-12-05 12:26:40

相关问题