2009-07-19 7 views
4

J'écris une méthode qui doit vérifier certains paramètres et s'ils sont validés, retourner un IEnumerable. Par exemple.Iterator & Exceptions nommés

public static IEnumerable<double> GetEnum(int param) 
{ 
    if (!IsValidParameter(param)) 
    { 
     throw new Exception(); 
    } 

    while(true) 
    { 
     yield return 5.0; 
    } 
} 

Cependant, je crois que l'évaluation paresseuse, quand je lance mes tests unitaires avec de mauvais paramètres, mais ne pas appeler l'une des méthodes IEnumerable encore, l'exception n'est pas levée.

[Test] 
[ExpectedException(typeof(Exception))] 
void Test() 
{ 
    var ie = GetEnum(bad_param); 
} 

Je peux arranger les choses en construisant IEnumerable dans une autre fonction (dire Foo), puis vérifiez les paramètres dans GetEnum et appeler Foo, mais est-il une solution sans avoir à créer de multiples fonctions?

Cheers, Jurgen

Répondre

9

En raison de la façon dont les blocs de iterator sont définis, il faut actuellement deux méthodes pour y parvenir:

public static IEnumerable<double> GetEnum(int param) { 
    if (!IsValidParameter(param)) { 
     throw new Exception(); 
    } 
    return GetEnumCore(param); 
} 
private static IEnumerable<double> GetEnumCore(int param) { 
    while(true) { 
     yield return 5.0; 
    } 
} 

Seul le bloc iterator (GetEnumCore) est reportée; GetEnum s'exécute immédiatement, effectuant vos vérifications.

+0

Je me suis en fait demandé si le compilateur était assez intelligent pour réduire les deux méthodes en un seul bloc d'itérateur. Merci pour le conseil, Marc. –

2

Pourriez-vous peut-être juste lancer l'itération en utilisant le recenseur sous-jacente?

[Test] 
[ExpectedException(typeof(Exception))] 
void Test() 
{ 
    var ie = GetEnum(bad_param); 
    var en = ie.GetEnumerator(); 
    en.MoveNext(); 
} 
+0

Je comprends ce comportement paresseux de l'énumérateur, est-il impossible de lancer l'exception avant? Dites dans le constructeur de la classe qui est générée pour l'itération nommée? – Jurgen

2

Tant que vous ne commencez pas à énumérer votre méthode, elle ne sera jamais appelée. Vous pouvez essayer énumérer dans votre test:

var ie = GetEnum(bad_param).First();