2014-12-04 38 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

相關問題