J'utilise la déclaration ci-dessous avec l'intention d'obtenir tous les objets de la machine de la collection MachineList
(type IEnumerable) qui ont un MachineStatus
de i. La collection MachineList
ne contient pas toujours les machines dont le statut est i.une collection vide quand Linq où ne retourne rien
À des moments où aucune machine n'a un MachineStatus
de i Je voudrais retourner une collection vide. Mon appel à ActiveMachines
(qui est utilisé en premier) fonctionne mais InactiveMachines
ne fonctionne pas.
public IEnumerable<Machine> ActiveMachines
{
get
{
return Customer.MachineList
.Where(m => m.MachineStatus == "a");
}
}
public IEnumerable<Machine> InactiveMachines
{
get
{
return Customer.MachineList
.Where(m => m.MachineStatus == "i");
}
}
Modifier
Un examen plus poussé, il semble que toute énumération des MachineList
entraînera énumérations suivants du MachineList
jeter un exeception: Object reference not set to an instance of an object
.
Par conséquent, peu importe si un appel est fait à ActiveMachines
ou InactiveMachines
comme son un problème avec la collection MachineList
. Ceci est particulièrement troublant parce que je peux casser les appels à MachineList
simplement en l'énumérant dans une montre avant qu'elle soit appelée dans le code. Au niveau le plus bas, MachineList
implémente NHibernate.IQuery
renvoyé comme IEnumerable
. Qu'est-ce qui fait que MachineList
perd son contenu après une énumération initiale?
Non, rien spécial arrive à l'énumération; il serait intéressant de voir ce que "inactif" etc sont dans le débogueur. Je me demande aussi si (par exemple) 'MachineStatus' est une propriété de façade qui lance une exception - c'est-à-dire' chaîne publique MachineStatus {get {return someInnerField.Status;}} 'et' someInnerField' est 'null'. –
Le vrai problème est que vous êtes en train d'énumérer un 'IEnumerable' plusieurs fois. Le contrat implicite que vous acceptez lorsque vous consommez «IEnumerable» est de ne l'énumérer qu'une seule fois! Donc, la vraie réponse n'est pas que votre collègue change son code pour permettre l'énumération multiple, mais que vous fassiez 'Customer.MachineList.ToList()' à un moment donné, puis que vous n'utilisiez la liste résultante qu'après (ou, obtenez un nouveau 'IEnumerable' à nouveau). Vous pouvez faire une évaluation paresseuse; vous pouvez le mettre en cache, mais ne l'enumez pas deux fois. Vous pouvez également exposer un 'IQueryable' et l'appeler plusieurs fois, aussi. – ErikE