c# - LINQ 查询执行投影,跳过或包装源在 IEnumerable.GetNext() 上抛出的异常

标签 c# linq exception-handling ienumerable word-wrap

我想要一个通用解决方案,但作为示例,假设我有一个 IEnumerable<string> ,其中有些可以解析为整数,有些则不能。

var strings = new string[] { "1", "2", "notint", "3" };

显然如果我做了 Select(s => int.Parse(s, temp))枚举时会抛出异常。

在这种情况下我可以做 .All(s => int.TryParse(s, out temp))首先,但是我想要一个通用的解决方案,我不必枚举 IEnumerable两次。

理想情况下,我希望能够执行以下操作,这会调用我的魔术异常跳过方法:

// e.g. parsing strings
var strings = new string[] { "1", "2", "notint", "3" };
var numbers = strings.Select(s => int.Parse(s)).SkipExceptions();
// e.g. encountering null object
var objects = new object[] { new object(), new object(), null, new object() }
var objecttostrings = objects.Select(o => o.ToString()).SkipExceptions();
// e.g. calling a method that could throw
var myClassInstances = new MyClass[] { new MyClass(), new MyClass(CauseMethodToThrow:true) };
var myClassResultOfMethod = myClassInstances.Select(mci => mci.MethodThatCouldThrow()).SkipExceptions();

我怎么写SkipExceptions()扩展方法?


关于 SelectSkipExceptions() 的一些很好的答案方法,但是我想知道是否 SkipExceptions()可以按照与 AsParallel() 相同的方式创建方法.

最佳答案

这个怎么样(你可能想给这个特殊的选择扩展一个更好的名字)

public static IEnumerable<TOutput> SelectIgnoringExceptions<TInput, TOutput>(
    this IEnumerable<TInput> values, Func<TInput, TOutput> selector)
   {
        foreach (var item in values)
        {
            TOutput output = default(TOutput);

            try
            {
                output = selector(item);
            }
            catch 
            {
                continue;
            }

            yield return output;
        }
    }

编辑5 添加using语句,感谢评论中的建议

    public static IEnumerable<T> SkipExceptions<T>(
        this IEnumerable<T> values)
    {
        using(var enumerator = values.GetEnumerator())
        {
           bool next = true;
           while (next)
           {
               try
               {
                   next = enumerator.MoveNext();
               }
               catch
               {
                   continue;
               }

               if(next) yield return enumerator.Current;
           } 
        }
    }

然而,这依赖于传入的 IEnumerable 尚未被前面的函数创建为列表(因此已经抛出异常)。例如。如果你这样调用它,这可能起作用:Select(..).ToList().SkipExceptions()

关于c# - LINQ 查询执行投影,跳过或包装源在 IEnumerable.GetNext() 上抛出的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7188623/

相关文章:

c# - 将 DataTable(动态列)转换为 List<T>

c# - 在哈希集字典中查找值的组合

java - 链式异常的优点是什么

c# - try-catch block

java - 如何捕获 JSP 文件中的异常?

c# - 枚举表达式列表以过滤集合

c# - Azure 持续部署 - Code First 迁移播种问题 (MVC 5)

c# - 4 个字节到十进制 - C# 来自 Windev

c# - 当返回类型为 IHttpActionResult 时,Web API 2 返回不带引号的简单字符串

c# - 分层数据的高级LINQ分组和投影查询(EF 4.0 + LINQ + ASP.NET MVC + HighCharts)