2010-09-03 87 views
0

我有一個需要反序列化的JSON「多級」響應,並且需要從反序列化的類結構中提取某個類的所有對象。Linq提取對象

在我使用的代碼下面,最後我發現我的結果是空的,沒有填充。

// given these two classes: 
[DataContract] 
public class ThingsList 
{ 
    [DataMember(Name = "status")] 
    public string Status { get; set; } 
    [DataMember(Name = "since")] 
    public double Since { get; set; } 
    [DataMember(Name = "list")] 
    public Dictionary<string, ThingsListItem> Items { get; set; } 
    public DateTime SinceDate { get { return UnixTime.ToDateTime(Since); } } 
} 
[DataContract] 
public class ThingsListItem 
{ 
    [DataMember(Name = "url")] 
    public string Url { get; set; } 
    [DataMember(Name = "title")] 
    public string Title { get; set; } 
}  

// I can deserialize my json to this structure with: 
ThingsList results = JsonConvert.DeserializeObject<ThingsList>(e.Result); 

// now I need to "extract" only the ThingsListItem objects, and I'm trying this: 
var theList = from item in results.Items.OfType<ThingsListItem>() 
     select new 
        { 
         Title = item.Title, 
         Url = item.Url 
        }; 
// but "theList" is not populated. 

的點這裏是(我相信): - 我嘗試使用results.Items.OfType()以只提取ThingsListItem對象,在「上」類中聲明在 公共字典項目{get;組; } 行。

有什麼想法?告訴我們,如果現在還不清楚......

感謝 安德烈

+3

項目是Dictionary 而不是'ThingsListItem'。也許你的意思是'results.Items.Values.OfType '? – 2010-09-03 16:31:48

回答

2

編輯:更新了我的清晰迴應。

由於您的字典值的類型爲ThingsListItem,因此您可以使用字典的Values屬性直接訪問它們。沒有必要使用OfType來檢查它們的類型並提取它們。只需使用:

var items = results.Items.Values; 

Values屬性將返回一個ICollection<ThingsListItem>。然後你可以用foreach迭代結果。 LINQ不必使用。


雖然上述Values屬性應該是足夠了,我要指出的一些問題與原來的LINQ查詢的嘗試。

1)下面的查詢可能是你以後的問題。再次,字典的Values屬性是關鍵(沒有雙關語意)來訪問的項目:

var theList = from item in results.Items.Values 
       select new 
       { 
        Title = item.Title, 
        Url = item.Url 
       }; 

2)你爲什麼要使用new?這將返回一個IEnumerable的匿名類型。你已經有了一個定義好的類,那麼爲什麼要投入一個新的匿名類型呢?你應該選擇的項目保留底層ThingsListItem項目直接獲得一個IEnumerable<ThingsListItem>

var theList = from item in results.Items.Values 
       select item; 
foreach (var item in theList) 
{ 
    Console.WriteLine("Title: {0}, Url: {1}", item.Title, item.Url); 
} 

您通常會投射到一個新的匿名類型來定義與你有興趣的數據屬性類型通常你會使用它們緊接在查詢之後,而對現有類的選擇可以立即使用或傳遞給期望該類型的其他方法。

希望這已經爲您解決了一些問題,並且您有更好的使用LINQ和何時使用new關鍵字的想法。重申,爲了您的目的,Values屬性應該就足夠了。當有其他直接手段時,使用LINQ選擇項目是多餘的。

+0

你可以用.First()封裝linq語句,它將返回一個ThingsListItem而不是它們的列表。 – Gage 2010-09-03 16:46:47

+0

爲什麼在後者中有多餘的LINQ查詢?直接寫'results.Items.Values'即可。 – Timwi 2010-09-03 17:04:18

+0

@Timwi:我剛剛編輯提到這一點。感謝您的反饋:) – 2010-09-03 17:06:46