I\'ve got a C# string extension method that should return an IEnumerable
of all the indexes of a substring within a string. It works perfectly for it
You have an iterator block. None of the code in that method is ever run outside of calls to MoveNext
on the returned iterator. Calling the method does noting but create the state machine, and that won't ever fail (outside of extremes such as out of memory errors, stack overflows, or thread abort exceptions).
When you actually attempt to iterate the sequence you'll get the exceptions.
This is why the LINQ methods actually need two methods to have the error handling semantics they desire. They have a private method that is an iterator block, and then a non-iterator block method that does nothing but do the argument validation (so that it can be done eagerly, rather than it being deferred) while still deferring all other functionality.
So this is the general pattern:
public static IEnumerable Foo(
this IEnumerable souce, Func anotherArgument)
{
//note, not an iterator block
if(anotherArgument == null)
{
//TODO make a fuss
}
return FooImpl(source, anotherArgument);
}
private static IEnumerable FooImpl(
IEnumerable souce, Func anotherArgument)
{
//TODO actual implementation as an iterator block
yield break;
}