I have a class with an API that allows me to ask for objects until it throws an IndexOutOfBoundsException
.
I want to wrap it into an iterator, to be able to write cleaner code. However, I need to catch the exception to stop iterating:
static IEnumerable<object> Iterator( ExAPI api ) {
try {
for( int i = 0; true; ++i ) {
yield return api[i]; // will throw eventually
}
}
catch( IndexOutOfBoundsException ) {
// expected: end of iteration.
}
}
But...
When used with expression, a yield return statement cannot appear in a catch block or in a try block that has one or more catch clauses. For more information, see Exception Handling Statements (C# Reference).Statements (C# Reference). (from the msdn)
How can I still wrap this api?
You simply need to move the yield return
statement outside of the try
block, like this:
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;
}
}
You can wrap the simple operation of getting the object into a separate function. You can catch the exception in there:
bool TryGetObject( ExAPI api, int idx, out object obj )
{
try
{
obj = api[idx];
return true;
}
catch( IndexOutOfBoundsException )
{
return false;
}
}
Then, call that function and terminate if necessary:
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;
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With