2010-07-07 1 views
3

grâce à Rex M for this bit of wisdom spéciales:Je veux vérifier le nombre d'un IEnumerable mais c'est très inefficace. De l'aide?

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

Après avoir trouvé tous un amis utilisateurs, je dois leur montrer une forme WPF. J'ai un problème que tous les utilisateurs n'ont pas au moins 5 amis, certains n'ont même pas d'amis! Voici ce que j'ai:

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

Donc, cette question comporte deux parties:

  1. Comment proposez-vous que je Manipulez le nombre variable d'amis d'un utilisateur peut avoir. Avec mon code actuel si un utilisateur n'a pas d'amis, j'obtiens une exception IndexOutOfBounds parce que friendsList [0] n'existe pas.

  2. Comment puis-je gérer plus efficacement la validation du fait qu'un utilisateur ait ou non des amis? Appeler .ToList() semble très taxant.

Répondre

1

Lorsque vous appelez ToList() sur un IEnumerable, vous devez énumérer tous les éléments de la liste énumérable et placer les résultats dans un conteneur. Donc une "odeur de code" est un code qui appelle ToList() plusieurs fois sur le même IEnumerable, il ne doit être fait qu'une seule fois et sauvegardé dans une variable.

Il existe une règle simple. Si vous travaillez sur la liste IEnumerable dans son ensemble (expressions Linq) ou simplement naviguer dans la liste du début à la fin, utilisez IEnumerable, si vous avez besoin d'accéder à une liste par index, ou comptez le nombre d'éléments ou naviguez dans les deux directions. liste, créez d'abord un conteneur List et utilisez-le.

-à-dire

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

Maintenant, en ce qui concerne le cas il y a quelque chose dans votre liste ou non, comme un couple de personnes ici ont mentionné, vous pouvez utiliser la liaison de données et un contrôle comme ItemsControl, mais si vous faites vouloir construire des choses UI up dynamiquement utiliser une boucle, ne pas indexer dans le tableau.

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

1) Databind la liste d'amis à ListBox. Vous pouvez utiliser des modèles de données pour afficher des images et des étiquettes.

2) Appelez Any().

2

Dans ce cas, appelez simplement ToList() une fois avant l'instruction if plutôt que de créer une liste à chaque fois.

EDIT

Vous voudrez peut-être regarder le modèle MVVM et ont XAML pour lier les contrôles aux données

+0

Ceci est une bonne optimisation locale. Cependant, il n'est même pas nécessaire de convertir en liste, puisque l'OP a déjà un 'IEnumerable', qui peut être itéré en utilisant' foreach'. –

+0

Ah oui c'est vrai – aqwert

+0

Bien que par les regards il a statiquement créé friend1, friend2 etc. ce qui pourrait rendre difficile l'utilisation foreach car il devrait y avoir des contrôles conditionnels supplémentaires quant à l'index que vous regardez. Ma première suggestion a gardé le nombre de changements à un simple refactoring – aqwert

1

Utilisez une sorte de contrôle ItemContainer, comme toute . Vous venez de spécifier un modèle pour ce que l'élément devrait ressembler, et de définir sa ItemsSource propriété:

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

Cela montrera jusqu'à 4 amis, en répétant le modèle autant de fois qu'il a besoin, mais aussi peu comme 0 si la collection est vide.

Questions connexes