Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Named Iterator & Exceptions

I am writing a method which needs to check some parameters and if they are validated return an IEnumerable. E.g.

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

    while(true)
    {
        yield return 5.0;
    }
}

However, I believe because of lazy evaluation, when I run my unit tests with bad parameters, but don't call any of the IEnumerable methods yet, the Exception is not thrown.

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

I can fix things by building the IEnumerable in another function (say Foo), then check parameters in GetEnum and call Foo but is there a solution without having to create multiple functions?

Cheers, Jurgen

like image 546
Jurgen Avatar asked Dec 14 '22 03:12

Jurgen


2 Answers

Due to how iterator blocks are defined, you currently need two methods to achieve this:

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;
    }
}

Only the iterator block (GetEnumCore) is deferred; GetEnum runs immediately, performing your checks.

like image 133
Marc Gravell Avatar answered Jan 02 '23 20:01

Marc Gravell


Could you maybe just initiate the iteration using the underlying enumerator?

[Test]
[ExpectedException(typeof(Exception))]
void Test()
{
    var ie = GetEnum(bad_param);
    var en = ie.GetEnumerator();
    en.MoveNext();
}
like image 40
Matt Hamilton Avatar answered Jan 02 '23 20:01

Matt Hamilton