Comment définir un type d'interface d'itérateur?
J'ai écrit une classe qui implémente IEnumerable<T>
. J'ai une méthode qui retourne MyClass
. Si j'essaie de yield return
de l'intérieur de cette méthode, le compilateur me dit "... ne peut pas être un itérateur bloc parce que ... ce n'est pas un itérateur interface de type".
Alors, comment puis-je définir ma propre interface iterator type? A-t-elle à être "abstrait" (ne peut pas toutes les méthodes définies)?
Ce que je veux faire est d'écrire un tas de chaînage de méthodes, de sorte que chaque méthode doit retourner une instance de MyClass
. Mais j'ai besoin de MyClass
à être une sorte de énumérable. Plutôt que d'utiliser certains sous-jacent type de données, j'espérais que je pourrais juste yield return
partout.
@Oded:
class SharpQuery : IEnumerable<HtmlNode>
{
public SharpQuery Find(string selector)
{
foreach (var n in this)
{
//filter the results
yield return node;
}
}
}
OriginalL'auteur mpen | 2010-09-26
Vous devez vous connecter pour publier un commentaire.
Non, ce n'est pas possible. Pour voir pourquoi considérez que vous avez une classe
Zoo
qui implémenteIEnumerable<Animal>
mais aussi a beaucoup d'autres membres. UnZoo
est unIEnumerable<Animal>
mais pas nécessairement vice versa - une séquence d'animaux est tout simplement une séquence d'animaux. Il n'y a pas de gardien du zoo, pas de commerces, pas de frais d'entrée ni de toutes les autres choses qui rend un zoo un zoo.Lorsque vous utilisez
yield return x
le type de retour ne peut pas êtreZoo
parce que vous ne disposez pas d'un zoo - vous avez juste une séquence d'animaux.Ce que vous pouvez faire à la place est de l'appeler comme
new Zoo(foo())
oùfoo
retourne unIEnumerable<Animal>
et ajouter un constructeur àZoo
qui accepte unIEnumerable<Animal>
.Zoo
n'ont pas toutes les données, il suffit d'méthodes?Si vous n'avez qu'méthodes que vous pouvez mettre en œuvre que les méthodes d'extension sur
IEnumerable<Animal>
. Alors je pense que vous obtenez ce que vous vouliez - vous pouvez facilement utiliser le rendement, et vous pouvez avoir d'autres méthodes spécialisées sur vos séquences.J'ai besoin d'un constructeur... ce qui donnerait un élément je pense. Alors je suppose que je pourrais simplement utiliser une fonction publique à la place. Je dois penser à tout ceci un peu plus... si j'ai vraiment envie de me contraindre à un apatride en classe... c'est une bonne idée. Merci!
OriginalL'auteur Mark Byers
Conformément à la section 8.2 de la Spécification du Langage C# Version 4.0:
L'article 10.14 spécifie que le type de retour d'un itérateur doit être l'un des suivants:
IEnumerator
IEnumerable
IEnumerator<T>
IEnumerable<T>
Conformément à l'article 10.14.4, en invoquant un itérateur n'est pas immédiatement exécuter le code dans le bloc itérateur. Au lieu de cela, un objet énumérateur qui implémente les interfaces suivantes est créé et retourné:
IEnumerator
IEnumerator<T>
IDisposable
L'objet énumérateur est généralement une instance d'un générées par le compilateur classe imbriquée avec salle d'accessibilité.
Par msdn.microsoft.com/en-us/library/ms228593.aspx le C# spec est installé avec Visual Studio en
Program Files (x86)/Microsoft Visual Studio 12.0/VC#/Specifications/1033
. Changement de version de visual studio comme approprié, 14.0 pour VS2015, etcOriginalL'auteur Ryan Prechel
Je pense que lorsque vous utilisez
yield return x
vous produira unIEnumerable
de type X. Donc dans votre cas il serait IEnumerableHéritant d'une classe ne serait pas automatiquement convertie implicitement lui-même à ce type. Donc si vous écrivez
il fonctionne. IEnumerable est pas le même que SharpQuery.
Bonne prise. Oui effectivement c'est une dépouillé version. SharpQuery ne pas mettre en œuvre IEnumerable, mais le retour de Trouver fonctionnera. J'ai corrigé.
OriginalL'auteur abhishek