代码之家  ›  专栏  ›  技术社区  ›  xtofl Adam Rosenfield

.NET迭代器来包装抛出API

  •  7
  • xtofl Adam Rosenfield  · 技术社区  · 14 年前

    我有一个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.
        }
    }
    

    当与表达式一起使用时,屈服 返回语句不能出现在 catch块或try块中 一个或多个catch子句。更多 信息,请参见异常处理 陈述(C#引用)。陈述(C#引用)。 (来自 msdn

    我怎么还能包装这个api呢?

    5 回复  |  直到 14 年前
        1
  •  14
  •   SLaks    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;
        } 
    }
    
        2
  •  4
  •   Timbo    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;
            }
        }
    }
    
        3
  •  0
  •   AHM    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;
            }
        }
    }
    
        4
  •  0
  •   Joshua Evensen    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;
    }
    

    虽然现在我在这里看,以上的答案是更好的我相信。一条石板被贴上了。

        5
  •  0
  •   QrystaL    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;
            }
        }