2011-08-25 4 views
1

Je code suivant:question bizarre IEnumerable <T> collection

IEnumerable<TreeItem> rootTreeItems = BuildRootTreeItems(); 

BuildTreeView(rootTreeItems.ElementAt(0)); 

private static void BuildTreeView(TreeItem treeItem) 
    { 
     TreeItem subMenuTreeItem = new TreeItem(); 
     subMenuTreeItem.Header = "1"; 

     TreeItem subMenuTreeItem2 = new TreeItem(); 
     subMenuTreeItem.Header = "2"; 

     treeItem.TreeItems.Add(subMenuTreeItem); 
     treeItem.TreeItems.Add(subMenuTreeItem2); 
    } 

La chose étrange est après le retour de BuildTreeView, le premier élément de rootTreeItems ne pas avoir de nœuds enfants, alors qu'il a vraiment lors du débogage dans la méthode BuildTreeView.

Ce problème m'a vraiment embrouillé pendant longtemps, quelqu'un a une idée? Merci beaucoup.

+0

Est-ce que 'BuildRootTreeItems' renvoie une expression LINQ? – Gabe

+0

en utilisant yield return pour renvoyer l'élément de l'arbre, mais en utilisant un paramètre qui est également IEnumerable type –

+0

Oui, 'yield return' provoquera également ce problème. – Gabe

Répondre

3

Vous rencontrez probablement un problème d'exécution différée avec IEnumerable<>. La chose à retenir est que votre IEnumerable<TreeItem> rootTreeItems n'est pas une liste, mais plutôt une promesse d'obtenir une liste à chaque fois qu'on lui demande de le faire.

Donc, si BuildRootTreeItems() crée l'IEnumerable<TreeItem> en utilisant une requête LINQ et il ne force pas l'exécution de la requête en utilisant .ToList() ou .ToArray() alors chaque fois que vous utilisez rootTreeItems vous réexécutant la requête dans BuildRootTreeItems()

L'appel au rootTreeItems.ElementAt(0) provoquera l'exécution de la requête. Si plus tard vous essayez d'appeler à nouveau rootTreeItems.ElementAt(0), vous réexécutez la requête et récupérez une autre instance du premier TreeItem.

Essayez de changer la première ligne comme ceci:

IEnumerable<TreeItem> rootTreeItems = BuildRootTreeItems().ToArray(); 

Cela force l'exécution et empêcher la ré-exécution ultérieure. Je parie que votre problème disparaît.

+0

Merci, mec, maintenant je suis plus clair sur ce qui se passe, ToList() m'aide à résoudre le problème, mais ce que je suis encore confus, c'est que je n'ai touché qu'une seule fois rootTreeItems.ElementAt (0), comment les enfants ne peuvent pas être ajouté –

1

Il est possible que votre méthode BuildRootTreeItems() retourne IEnumerable interface quels éléments sont créés via yield statement ou comme Gabe mentionné dans le commentaire ci-dessus une implémentation de IEnumerable qui est créée via la chaîne d'expressions Linq contenant Select method.

Cela peut conduire à recréer des éléments de IEnumerable à chaque accès à un élément de l'énumération ou à l'itérer via les expressions Linq ou l'instruction foreach.

0

Je vais simplier:

Cela pourrait également se produire si

A) TreeItem est un type de valeur (struct)

B) TreeItem.TreeItems retourne une nouvelle collection

Mais l'exactitude de ceci est difficile à déduire seulement du code fourni.

+0

1. TreeItem n'est pas un type de valeur –

+0

2. TreeItems est toujours la même colloction créée lors de la construction de la classe –

Questions connexes