本文介绍了LINQ查询来执行投影,跳跃或包装异常,其中源IEnumerable.GetNext抛出()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想一个常规解决方案但作为一个例子,假设我有一个的IEnumerable<串> ,其中有些可以解析为整数,而有些却不能。

I'd like a general solution but as an example, assume i have an IEnumerable<string>, where some can be parsed as integers, and some cannot.

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



显然,如果我这样做选择(S = GT; int.Parse(S ,温度))枚举的时候它会抛出异常。

Obviously if i did Select(s => int.Parse(s, temp)) it'd throw an exception when enumerated.

在这种情况下,我可以做。所有( S => int.TryParse(S,出温度))第一,但是我想在那里我不必一一列举了 IEnumerable的一个通用的解决方案两次

In this case i could do .All(s => int.TryParse(s, out temp)) first, however i want a general solution where i don't have to enumerate the IEnumerable twice.

在理想情况下,我想能做到以下几点,这就要求我的魔法异常跳绳方法:

Ideally i'd like to be able to do the following, which calls my magic exception skipping method:

// 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()

Some great answers for a SelectSkipExceptions() method, however i wonder if a SkipExceptions() method could be created, along the same lines as AsParallel().

推荐答案

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

How about this (you might want to give this special Select Extension a better name)

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

Edit5
的加成using语句,感谢您的意见建议

Edit5Added a using statement, thanks for the suggestion in comments

    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的尚未创建(并因此已经有抛出的异常)由前面的功能列表。例如。这很可能的不可以工作,如果你这样称呼它:选择(..)了ToList()SkipExceptions()

However this relies on the incoming IEnumerable not already being created (and therefore already having thrown Exceptions) as a list by the preceding Function. E.g. this would probably not work if you call it like this: Select(..).ToList().SkipExceptions()

这篇关于LINQ查询来执行投影,跳跃或包装异常,其中源IEnumerable.GetNext抛出()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-27 19:33