8
votes

.NET Itérateur à envelopper API

J'ai une classe avec une API qui me permet de demander des objets jusqu'à ce qu'il jette un indexporofboundsexception .

Je veux envelopper dans un itérateur, pour pouvoir écrire un code de nettoyage. Cependant, j'ai besoin d'attraper l'exception pour arrêter itérant: xxx

mais ...

Lorsqu'il est utilisé avec expression, un rendement La déclaration de retour ne peut pas apparaître dans un bloc de capture ou dans un bloc d'essai qui a une ou plusieurs clauses de capture. Pour plus Information, voir la manipulation des exceptions Déclarations (C # Référence) .statifs (C # Référence). (du MSDN )

Comment puis-je toujours envelopper cette API?


0 commentaires

5 Réponses :


15
votes

Vous devez simplement déplacer la déclaration code> Rendement code> en dehors du bloc code> Essayez CODE> Bloc, comme celui-ci:

static IEnumerable<object> Iterator( ExAPI api ) {
   for( int i = 0; true; ++i ) {
        object current;
        try {
            current = api[i];
        } catch(IndexOutOfBoundsException) { yield break; }

        yield return current;
    } 
}


3 commentaires

Bien que vous n'ayez pas besoin d'un "if (actuel! = null) rendement de rendement"?


Oh, attends im Dumb, j'ai raté la pause de rendement.


La documentation relative à la pause de rendement est laissée sur le MSDN ... Merci d'avoir souligné!



0
votes

Il suffit de réorganiser le code:

static IEnumerable<object> Iterator( ExAPI api ) {
    bool exceptionThrown = false;
    object obj = null;
    for( int i = 0; true; ++i ) {
        try {
            obj = api[i];
        }
        catch( IndexOutOfBoundsException ) {
            exceptionThrown = true;
            yield break;
        }

        if (!exceptionThrown) {
            yield return obj;
        }
    }
}


3 commentaires

Non, j'ai écrit trop vite, je suppose ... Quoi qu'il en soit, votre réponse ci-dessous est plus propre et meilleure :-)


Maintenant, vous avez une variable inutile.


Ouais - mais si j'avais changé cela, ma réponse serait une copie directe de votre réponse, et ce serait une sorte de boiteux, même si c'est correct - vous avez écrit le bon code, vous devriez obtenir le crédit!



4
votes

Vous pouvez envelopper le fonctionnement simple d'obtenir l'objet dans une fonction distincte. Vous pouvez attraper l'exception là-bas: xxx pré>

puis, appelez cette fonction et terminez si nécessaire: P>

static IEnumerable<object> Iterator( ExAPI api )
{
   bool abort = false;

    for( int i = 0; !abort; ++i )
    {
        object obj;
        if( TryGetObject( api, i, out obj ) )
        {
            yield return obj;
        }
        else
        {
            abort = true;
        }
    }
}


1 commentaires

Je ne suis pas vraiment fan de cette approche. Si l'API ne va pas être accessible dans cette méthode, une méthode distincte pour obtenir l'objet est un peu redondante.



0
votes

Si vous ne pouvez pas vérifier les limites de l'objet, vous pouvez faire quelque chose comme celui-ci xxx

bien que je regarde ici, la réponse ci-dessus est meilleure je crois. Le seul Slass Publié.


1 commentaires

En effet: mon intention est de ne pas remplir un conteneur, mais plutôt de fournir un itérateur.



0
votes
    static IEnumerable<object> Iterator(ExAPI api)
    {
        int i = 0;
        while (true)
        {
            Object a;
            try
            {
                a = api[i++];
            }
            catch (IndexOutOfBoundsException)
            {
                yield break;
            }
            yield return a;
        }
    }

0 commentaires