Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .NET迭代器来包装API_C#_.net_Exception_Yield Return - Fatal编程技术网

C# .NET迭代器来包装API

C# .NET迭代器来包装API,c#,.net,exception,yield-return,C#,.net,Exception,Yield Return,我有一个带有API的类,它允许我请求对象,直到它抛出一个IndexOutOfBoundsException 我想把它包装成一个迭代器,以便能够编写更干净的代码。但是,我需要捕获异常以停止迭代: static IEnumerable<object> Iterator( ExAPI api ) { try { for( int i = 0; true; ++i ) { yield return api[i]; // will throw even

我有一个带有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.
    }
}
静态IEnumerable迭代器(ExAPI){
试一试{
for(int i=0;true;++i){
yield return api[i];//最终将抛出
}
} 
捕获(IndexOutOfBoundsException){
//预期:迭代结束。
}
}
但是

与表达式连用时,表示让步 return语句不能出现在 catch块或在具有 一个或多个catch子句。更多 有关详细信息,请参阅异常处理 语句(C#参考)。语句(C#参考)。 (摘自)


如何仍然包装此api?

您只需将
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;
    } 
}
静态IEnumerable迭代器(ExAPI){
for(int i=0;true;++i){
目标电流;
试一试{
当前=api[i];
}catch(IndexOutOfBoundsException){yield break;}
产生回流电流;
} 
}
只需重新排列代码:

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;
        }
    }
}
静态IEnumerable迭代器(ExAPI){
bool exceptionThrown=false;
objectobj=null;
for(int i=0;true;++i){
试一试{
obj=api[i];
}
捕获(IndexOutOfBoundsException){
exceptionThrown=true;
屈服断裂;
}
如果(!ExceptionRown){
收益率目标;
}
}
}

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

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;
        }
    }
}
静态IEnumerable迭代器(ExAPI)
{
bool abort=false;
对于(int i=0;!abort;++i)
{
对象对象对象;
if(TryGetObject(api、i、out obj))
{
收益率目标;
}
其他的
{
中止=真;
}
}
}

如果你根本无法检查对象的边界,你可以这样做

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;
}
静态IEnumerable迭代器(ExAPI)
{
列表输出=新列表();
尝试
{
for(int i=0;true;++i)
新增(api[i]);
} 
捕获(IndexOutOfBoundsException)
{
//预期:迭代结束。
}
返回输出;
}
虽然现在我看这里,我相信上面的答案更好。发布的一个。静态IEnumerable迭代器(ExAPI api)
    static IEnumerable<object> Iterator(ExAPI api)
    {
        int i = 0;
        while (true)
        {
            Object a;
            try
            {
                a = api[i++];
            }
            catch (IndexOutOfBoundsException)
            {
                yield break;
            }
            yield return a;
        }
    }
{ int i=0; while(true) { 对象a; 尝试 { a=api[i++]; } 捕获(IndexOutOfBoundsException) { 屈服断裂; } 收益率a; } }
不,我想我写得太快了。。。。不管怎样,你下面的答案更清晰更好:-)现在你有了一个无用的变量。是的-但是如果我改变了,我的答案将是你答案的直接副本,这将有点蹩脚,即使它是正确的-你写了正确的代码,你应该得到学分!我不太喜欢这种方法。如果api仅通过此方法访问,则获取对象的单独方法有点多余。尽管您不需要“If(current!=null)yield return current”?哦,等等,我错过了yield break。msdn上没有
yield break
语句文档。。。谢谢你的指点!事实上:我的意图不是填充容器,而是提供迭代器。