Linq提取对象

时间:2010-09-03 16:28:28

标签: c# linq

我有一个JSON“多级”响应,我需要反序列化,并且从反序列化的类结构中我需要提取某个类的所有对象。

在我正在使用的代码下面,最后我发现我的结果是空的,没有填充。

// 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对象,在“upper”类中声明 公共字典项{get;组; } 行。

有什么想法吗?告诉它是否不清楚......

由于 安德烈

1 个答案:

答案 0 :(得分:2)

编辑:为了清晰起见更新了我的回复。

由于您的词典值类型为ThingsListItem,因此您可以使用词典的Values属性直接访问它们。无需使用OfType检查其类型并将其提取出来。只需使用:

var items = results.Items.Values;

Values属性将返回ICollection<ThingsListItem>。然后,您可以使用foreach迭代结果。不必使用LINQ。


虽然上面描述的Values属性应该足够了,但我会指出原始LINQ查询尝试的一些问题。

1)以下查询可能就是你所追求的。同样,Dictionary的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选择项目是多余的。