代码之家  ›  专栏  ›  技术社区  ›  Benny

list.convertall和异常

  •  3
  • Benny  · 技术社区  · 14 年前

    如果convertall在一个元素上引发异常,我可以跳过这个元素继续下一个元素吗?

    3 回复  |  直到 12 年前
        1
  •  6
  •   Fredrik Mörk    14 年前

    不。例外情况需要在某个地方处理。如果您希望在转换器中发生异常(这对于应用程序来说是可以的),那么您必须在转换器中有一个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 ,但这不会引发异常…)

    然而,吃这种异常总是给人一种权宜之计的感觉,而且我不希望在代码中有任何异常。

        2
  •  1
  •   João Angelo    14 年前

    如果需要完全跳过抛出元素 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 或其他用于失败转换的唯一值,然后筛选结果以排除这些值不适用。

        3
  •  1
  •   Stefan de Kok    12 年前

    把弗雷德里克和萨米尔的答案组合起来,颠倒,缩短可能是最简单的。先应用where,然后转换所有:

    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块。