开发者

I want to check the Count of an IEnumerable but it's very inefficient

Special thanks to 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
        });
    }

After finding all of a users friends, I need to show them on a WPF form. I have a problem that not all users have at least 5 friends, some even have no friends! Here's what I have:

    private void showUserFriends()
    {
        if (friendsList.ToList().Count > 0)
        {
            friend1.Source = new BitmapImage(new Uri(friendsList.ToList()[0].Photo));
            label11.Content = friendsList.ToList()[0].Na开发者_JAVA百科me;

            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.
        }            
    }

So this question has two parts:

  1. How do you suggest I handle the varying number of friends a user might have. With my current code if a user has no friends I get an IndexOutOfBounds exception because friendsList[0] doesn't exist.

  2. How can I more efficiently handle the validation of whether or not a user has friends? Calling .ToList() seems very taxing.


1) Databind the friends list to a ListBox. You can use data templates to display images and labels.

2) Call Any().


In this case just call ToList() once before the if statement rather than creating a list everytime.

EDIT

You might want to look at the MVVM pattern and have XAML to bind the controls to the data


When you call ToList() on an IEnumerable what you are doing is Enumerating all the elements of the enumerable list and placing the results into a container. So a "code smell" is code that call's ToList() multiple times on the same IEnumerable, it should only be done once and saved to a variable.

There is a simple rule of thumb. If you are operating on the IEnumerable list as a whole (Linq expressions) or simply navigating the list from start to finish then use IEnumerable, if you need to access a list by index, or count the number of elements or navigate both directions through the list, create a List container first and use it.

i.e.

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

Now, with regards to if there is anything in your list or not, as a couple people here have mentioned, you can use data binding and a control like ItemsControl, but if you do want to build UI stuff up dynamically use a loop, don't index into the array.

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


Use some kind of ItemContainer control, such as any ItemsControl. You just specify a template for what the item should look like, and set its ItemsSource property:

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

This will show up to 4 friends, repeating the template as many times as it needs to, but as few as 0 if the collection is empty.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜