C# 对于这种简单的Linq使用,我的代码效率很低

C# 对于这种简单的Linq使用,我的代码效率很低,c#,.net,linq,linq-to-xml,C#,.net,Linq,Linq To Xml,我有下面的方法,它应该解析XML响应中的信息并返回用户集合 我选择创建一个Friend类并将列表返回给调用方法 这是我到目前为止所做的,但我注意到ids.ToList.Count方法将每个id元素解析为一个列表,然后在for条件中再次执行。它只是超级无效 public List<Friend> FindFriends() { List<Friend> friendList = new List<Friend>(); var friends =

我有下面的方法,它应该解析XML响应中的信息并返回用户集合

我选择创建一个Friend类并将列表返回给调用方法

这是我到目前为止所做的,但我注意到ids.ToList.Count方法将每个id元素解析为一个列表,然后在for条件中再次执行。它只是超级无效

public List<Friend> FindFriends()
{
    List<Friend> friendList = new List<Friend>();

    var friends = doc.Element("ipb").Element("profile").Element("friends").Elements("user");
    var ids = from fr in friends
              select fr.Element("id").Value;

    var names = from fr in friends
                select fr.Element("name").Value;

    var urls = from fr in friends
                select fr.Element("url").Value;

    var photos = from fr in friends
                select fr.Element("photo").Value;

    if (ids.ToList().Count > 0)
    {
        for (int i = 0; i < ids.ToList().Count; i++)
        {
            Friend buddy = new Friend();
            buddy.ID = ids.ToList()[i];
            buddy.Name = names.ToList()[i];
            buddy.URL = urls.ToList()[i];
            buddy.Photo = photos.ToList()[i];

            friendList.Add(buddy);
        }
    }            

    return friendList;
}

第一个问题-您必须返回列表吗?你能返回一个IEnumerable吗?如果是这样,性能会变得更好:

IEnumerable<Friend> FindFriends()
{
    return doc.Descendants("user").Select(user => new Friend {
        ID = user.Element("id").Value,
        Name = user.Element("name").Value,
        Url = user.Element("url").Value,
        Photo = user.Element("photo").Value
    });
}
这将创建一个投影,或者一个新对象,它只包含如何创建新的好友对象而不实际创建它们的所有逻辑,而不是实际创建新的bucket并向其中填充值。当调用者最终开始对IEnumerable进行foreach时,就会创建它们。这称为延迟执行

这也是一个假设——XML片段中的所有节点都是朋友。如果不是这样,那么XML选择的第一部分可能需要稍微复杂一些


正如@anon所指出的,即使您确实需要返回一个列表,因为您提供的信息中不明显的原因,您也可以在return语句的末尾调用.ToList。这将直接将我上面描述的投影执行到一个新的bucket中,因此您只能创建一个。

第一个问题-您必须返回一个列表吗?你能返回一个IEnumerable吗?如果是这样,性能会变得更好:

IEnumerable<Friend> FindFriends()
{
    return doc.Descendants("user").Select(user => new Friend {
        ID = user.Element("id").Value,
        Name = user.Element("name").Value,
        Url = user.Element("url").Value,
        Photo = user.Element("photo").Value
    });
}
这将创建一个投影,或者一个新对象,它只包含如何创建新的好友对象而不实际创建它们的所有逻辑,而不是实际创建新的bucket并向其中填充值。当调用者最终开始对IEnumerable进行foreach时,就会创建它们。这称为延迟执行

这也是一个假设——XML片段中的所有节点都是朋友。如果不是这样,那么XML选择的第一部分可能需要稍微复杂一些


正如@anon所指出的,即使您确实需要返回一个列表,因为您提供的信息中不明显的原因,您也可以在return语句的末尾调用.ToList。这将直接将我上面描述的投影执行到一个新的bucket中,因此您只能创建一个。

为什么需要单独的id/name/url/photos变量?把这一切结合起来。如果不需要列表,可以取消ToList调用

List<Friend> friendList = (from f in doc.Element("ipb").Element("profile").Element("friends").Elements("user")
                          select new Friend() { 
                                                 ID = f.Element("id").Value, 
                                                 Name = f.Element("name").Value,
                                                 URL = f.Element("url").Value,
                                                 Photo = f.Element("photo").Value
                                 }).ToList();

return friendList;

为什么需要单独的id/names/url/photos变量?把这一切结合起来。如果不需要列表,可以取消ToList调用

List<Friend> friendList = (from f in doc.Element("ipb").Element("profile").Element("friends").Elements("user")
                          select new Friend() { 
                                                 ID = f.Element("id").Value, 
                                                 Name = f.Element("name").Value,
                                                 URL = f.Element("url").Value,
                                                 Photo = f.Element("photo").Value
                                 }).ToList();

return friendList;

即使他们必须返回一个列表,打电话给ToList也会比他们现在做的更好。我不必返回列表,我只是习惯了使用它。我似乎总是忘了我的名字。谢谢,这段代码太棒了。我会测试一下,看看是否有效。再次感谢!即使他们必须返回一个列表,打电话给ToList也会比他们现在做的更好。我不必返回列表,我只是习惯了使用它。我似乎总是忘了我的名字。谢谢,这段代码太棒了。我会测试一下,看看是否有效。再次感谢!