tags:

views:

96

answers:

2

if ConvertAll throw an exception on one element, can i just skip this element and continue to the next element?

+4  A: 

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.

Fredrik Mörk
then the null will be put in to the converted list? no way to skip the failed one?
Benny
You could always use the `Where` method to filter the `null` values later.
Samir Talwar
@Benny; no, you can't get away with it from the start; the converter code must return a value. However, you can use the suggestion by @Samir and filter the resulting list.
Fredrik Mörk
+1  A: 

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.

João Angelo