如何返回使用LINQ创建的单个对象?

时间:2014-06-02 14:26:34

标签: c# xml linq linq-to-xml linq-to-objects

我有一个包含天气预报数据的XML文件。我试图通过XDocument查询它。我有一个名为“Forecast”的类,我正在尝试创建这种类型的对象,并使用LINQ填充它的属性,如下所示:

public Forecast CurrentConditions(string stateName, string cityName)
{
    var data = from i in weatherResponse.Descendants("current_observation")
               select new Forecast
               {
                   TemperatureC = Convert.ToDouble(i.Element("temp_c").Value)
                   //Setting other properties here
               };

    return data;
}

我的“预测”类只包含以下属性:

class Forecast
{
    public double TemperatureF { get; set; }
    public double TemperatureC { get; set; }
    public string RelativeHumidity { get; set; }
}

然而,VS突出显示return data;并说"Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<WeatherUnderground1.Forecast>' to 'WeatherUnderground1.Forecast'. An explicit conversion exists (are you missing a cast?)"

因此,如果我将其更改为:

return (Forecast)data;

我得到异常“未处理的异常:System.NullReferenceException:对象引用未设置为对象的实例。”

问题

我做错了什么,以及返回Forecast对象的正确方法是什么?

3 个答案:

答案 0 :(得分:1)

select正在返回IEnumerable<Forecast>,换句话说是一系列的,而不是一个。{1}}。如果你确定只有一个,你可以使用,

public Forecast CurrentConditions(string stateName, string cityName)
{
    var datas = from i in weatherResponse.Descendants("current_observation")
               select new Forecast
               {
                   TemperatureC = Convert.ToDouble(i.Element("temp_c").Value)
                   //Setting other properties here
               };

    return datas.SingleOrDefault(); // Or FirstOrDefault() or LastOrDefault()
}

但是,如果有多个,则返回null;这可能是你想要的,如果你需要在几个预测中做一些平均值。您可以使用datas.Count()了解返回的项目数量,并从那里开始。

答案 1 :(得分:0)

您的查询未选择单个预测。如果您只想要列表中的第一个,则可以使用FirstOrDefault()

return data.FirstOrDefault();

答案 2 :(得分:0)

您的查询返回IEnumerable<Forecast>。你想要归还那个,或者 您需要将FirstOrDefault()或SingleOrDefault()附加到查询中以返回单个项目。

public Forecast CurrentConditions(string stateName, string cityName)
{
    var data = from i in weatherResponse.Descendants("current_observation")
       select new Forecast
       {
           TemperatureC = Convert.ToDouble(i.Element("temp_c").Value)
           //Setting other properties here
       };

    //change this: return data;
    //to:
    return data.FirstOrDefault();
    //or (if you know for certain there can be no more than 1 item):
    return data.SingleOrDefault();
}