List.ConvertAll и исключение - PullRequest
       3

List.ConvertAll и исключение

3 голосов
/ 06 апреля 2010

если ConvertAll создает исключение для одного элемента, могу ли я просто пропустить этот элемент и перейти к следующему элементу?

Ответы [ 3 ]

6 голосов
/ 06 апреля 2010

Нет. Исключение нужно будет где-то обработать. Если вы ожидаете, что исключения будут происходить в конвертере (и это нормально для приложения), вы должны иметь try-catch внутри конвертера (следующий пример кода вернет null для неудачных преобразований):

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

(да, я знаю, что я должен был использовать int.TryParse, но это не исключение ...)

Тем не менее, употребление подобных исключений всегда дает запах обходного пути, и я ничего не хотел бы иметь в своем коде.

1 голос
/ 14 августа 2012

Проще всего объединить, перевернуть и сократить ответы, данные Фредриком и Самиром. Сначала примените Where, затем ConvertAll:

List<UnconvertedType> unconverted;

// do something to populate unconverted

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

Таким образом, вы можете удалить любые исключения, прежде чем они будут рассмотрены, и удалить блок try / catch.

1 голос
/ 06 апреля 2010

Если вам нужно полностью пропустить бросающий элемент, ConvertAll не принесет вам пользы, однако вы можете реализовать вспомогательный метод для "надежного перечисления". Как то так:

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

Я сделал бы это только в том случае, если возвращать null или другое уникальное значение для неудачных преобразований, а затем фильтровать результат, чтобы исключить эти значения, не применимо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...