.NET 迭代器包装抛出 API

发布于 2024-09-29 03:49:14 字数 707 浏览 0 评论 0原文

我有一个带有 API 的类,它允许我请求对象,直到它抛出 IndexOutOfBoundsException

我想将它包装到一个迭代器中,以便能够编写更清晰的代码。但是,我需要捕获异常以停止迭代:

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

但是......

当与表达式一起使用时,yield return 语句不能出现在 catch 块或在 try 块中 一个或多个 catch 子句。了解更多 信息,请参阅异常处理 语句(C# 参考)。语句(C# 参考)。 (来自 msdn

我怎样才能换行这个API?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

温柔一刀 2024-10-06 03:49:14

您只需将 yield return 语句移到 try 块之外,如下所示:

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 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;
    } 
}
热风软妹 2024-10-06 03:49:14

您可以将获取对象的简单操作包装到一个单独的函数中。您可以在那里捕获异常:

bool TryGetObject( ExAPI api, int idx, out object obj )
{
    try
    {
        obj = api[idx];
        return true;
    }
    catch( IndexOutOfBoundsException )
    {
        return false;
    }        
}

然后,调用该函数并在必要时终止:

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

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;
        }
    }
}
倒带 2024-10-06 03:49:14

只需重新排序代码:

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

Just reorder the 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;
        }
    }
}
何时共饮酒 2024-10-06 03:49:14

如果您根本无法检查对象的边界,您可以执行类似的操作,

static IEnumerable<object> Iterator( ExAPI api )
{
 List<object> output = new List<object>();
    try
 {
  for( int i = 0; true; ++i )
   output.Add(api[i]);
    } 
    catch( IndexOutOfBoundsException )
 {
  // expected: end of iteration.
    }
 return output;
}

尽管现在我正在看这里,我相信上面的答案更好。 SLAks 发布的一张。

If you can't check the bounds of the object at all, you could do something like this

static IEnumerable<object> Iterator( ExAPI api )
{
 List<object> output = new List<object>();
    try
 {
  for( int i = 0; true; ++i )
   output.Add(api[i]);
    } 
    catch( IndexOutOfBoundsException )
 {
  // expected: end of iteration.
    }
 return output;
}

although now that im looking here, the answer above is better i believe. The one SLaks posted.

撩心不撩汉 2024-10-06 03:49:14
    static IEnumerable<object> Iterator(ExAPI api)
    {
        int i = 0;
        while (true)
        {
            Object a;
            try
            {
                a = api[i++];
            }
            catch (IndexOutOfBoundsException)
            {
                yield break;
            }
            yield return a;
        }
    }
    static IEnumerable<object> Iterator(ExAPI api)
    {
        int i = 0;
        while (true)
        {
            Object a;
            try
            {
                a = api[i++];
            }
            catch (IndexOutOfBoundsException)
            {
                yield break;
            }
            yield return a;
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文