开发者

List.ConvertAll and exception

if ConvertAll throw an 开发者_StackOverflow中文版exception on one element, can i just skip this element and continue to the next element?


No. The exception will need to be handled somewhere. If you expect exceptions to happen in the converter (and this is OK for the application), you must have a try-catch within the converter (the following code sample will return null for failed conversions):

List<string> input = new List<string> { "1", "2", "three", "4" };

List<int?> converted = input.ConvertAll(s =>
{
    int? result = null;
    try
    {
        result = int.Parse(s);
    }
    catch (Exception) { }

    return result;
});

(yes, I know I should have used int.TryParse, but that would not throw an exception...)

However, eating exceptions like that always gives the smell of a workaround, and is nothing I would like to have in my code.


If you need to skip the throwing element entirely ConvertAll will not result for you, however you can implement a helper method for "robust enumeration". Something like this:

public static void Main(string[] args)
{
    var integers = new List<int>() { 1, 2, -5 };
    Converter<int, string> converter = x =>
    {
        if (x < 0)
            throw new NotSupportedException();

        return x.ToString();
    };

    // This code would throw
    //var result1 = integers.ConvertAll(converter).ToArray();
    //Console.WriteLine(String.Join(Environment.NewLine, result1));

    // This code ignores -5 element
    var result2 = RobustEnumerating(integers, converter).ToArray();
    Console.WriteLine(String.Join(Environment.NewLine, result2));
}

public static IEnumerable<K> RobustEnumerating<T, K>(IEnumerable<T> input,
    Converter<T, K> converter)
{
    List<K> results = new List<K>();
    foreach (T item in input)
    {
        try
        {
            results.Add(converter(item));
        }
        catch { continue; }
    }
    return results;
}

I would only do this if returning null or other unique value for failed conversions and then filtering the result to exclude those values is not applicable.


It may be simplest to combine, reverse, and shorten the answers given by Fredrik and Samir. Apply a Where first, then ConvertAll:

List<UnconvertedType> unconverted;

// do something to populate unconverted

List<ConvertedType> converted = unconverted.
    Where(ut => ut != null).
    ToList().
    ConvertAll<ConvertedType>(ut => ut as ConvertedType);

This way you can remove any exceptions before they get considered and can remove the try/catch block.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜