我想检查IEnumerable的Count,但效率非常低

时间:2010-07-07 03:46:28

标签: c# .net linq ienumerable

特别感谢Rex M for this bit of wisdom

    public IEnumerable<Friend> FindFriends()
    {
        //Many thanks to Rex-M for his help with this one.
        //https://stackoverflow.com/users/67/rex-m

        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
        });
    }

找到所有用户朋友后,我需要在WPF表单上显示它们。我有一个问题,并非所有用户都有至少5个朋友,有些甚至没有朋友!这就是我所拥有的:

    private void showUserFriends()
    {
        if (friendsList.ToList().Count > 0)
        {
            friend1.Source = new BitmapImage(new Uri(friendsList.ToList()[0].Photo));
            label11.Content = friendsList.ToList()[0].Name;

            friend2.Source = new BitmapImage(new Uri(friendsList.ToList()[1].Photo));
            label12.Content = friendsList.ToList()[1].Name;

            //And so on, two more times. I want to show 4 friends on the window.
        }            
    }

所以这个问题有两个部分:

  1. 您如何建议我处理用户可能拥有的不同数量的朋友。使用我当前的代码,如果用户没有朋友,我会得到一个IndexOutOfBounds异常,因为friendsList [0]不存在。

  2. 如何更有效地处理用户是否有朋友的验证?调用.ToList()似乎很费力。

4 个答案:

答案 0 :(得分:3)

1)将好友列表数据绑定到ListBox。您可以使用数据模板显示图像和标签。

2)致电Any()

答案 1 :(得分:2)

在这种情况下,只需在if语句之前调用ToList()一次,而不是每次都创建一个列表。

修改

您可能希望查看MVVM模式并使用XAML将控件绑定到数据

答案 2 :(得分:1)

使用某种ItemContainer控件,例如任何ItemsControl。您只需为项目的外观指定模板,并设置其ItemsSource属性:

myItemsControl.ItemsSource = new ObservableCollection(myFriends.Take(4));

这将显示最多 4位朋友,根据需要重复模板次数,但如果集合为空,则少至0次。

答案 3 :(得分:1)

当您在IEnumerable上调用ToList()时,您正在执行的操作是枚举可枚举列表的所有元素并将结果放入容器中。所以“代码味道”是在同一个IEnumerable上多次调用ToList()的代码,它应该只执行一次并保存到变量中。

有一个简单的经验法则。如果您作为一个整体在IEnumerable列表上运行(Linq表达式)或者只是从头到尾导航列表然后使用IEnumerable,如果您需要通过索引访问列表,或计算元素数量或导航两个方向通过列表,首先创建一个List容器并使用它。

即。

List<Friend> friends = FindFriends().ToList();
//Then use the friends list....

现在,关于你的列表中是否有任何内容,正如这里的几个人所提到的,你可以使用数据绑定和像ItemsControl这样的控件,但如果你确实想要动态构建UI,请使用循环,不要索引到数组。

List<Friend> friends = FindFriends().ToList();
if(friends.Count > 0)
{
  foreach(Friend f in friends)
  {
    //Create your Control(s) and add them to your form or panel's controls container
    // somthing like (untested) myPanel.Controls.Add(new Label(){Text = f.Name});
  }
}