【问题标题】:Unhandled Exception in List Sort列表排序中未处理的异常
【发布时间】:2009-11-19 20:58:01
【问题描述】:

所以,我有一个包含自定义类的列表,MyClass
MyClass 有属性,可以为空(但不应该是)。

当使用自定义排序器对此类进行排序时,排序器访问此 null 属性并引发异常,该异常被视为未处理,即使排序方法周围有一个 try-catch 块。

现在由于某种原因,异常仍然被写入控制台,这就是异常处理程序正在做的事情。

我有一个真正的应用程序存在同样的问题,导致我的单元测试失败,即使异常处理正确并且我无法解释这一点。

所以我附上了一些示例代码来更好地解释自己,从 VS 运行它。

更新代码
结果:
System.InvalidOperationException
无法比较数组中的两个元素。
完成!

所以它似乎正在处理我的 custom 异常,并抛出自己的异常?

using System;
using System.Collections.Generic;
using System.Data;

namespace TestSortException
{
    class Program
    {
        static void Main()
        {
            try
            {
                var list = new List<MyClass>
                                         {
                                             new MyClass("1"),
                                             new MyClass(null),
                                             new MyClass("fdsfsdf")
                                         };



                list.Sort(new MyClassSorter());
            }
            catch(Exception e)
            {
                Console.WriteLine(e.GetType());
                Console.WriteLine(e.Message);
            }

            Console.WriteLine("Done!");
            Console.ReadLine();

        }
    }

    class MyClassSorter : IComparer<MyClass>
    {
        public int Compare(MyClass x, MyClass y)
        {
//            try
//            {
                if (x.MyString == y.MyString)
                    return 0;
                // Unhandled??? Exception here
                if (x.MyString.Length > y.MyString.Length)
                    return 1;

                return -1;
//            }
//            catch (Exception)
//            {
//                return -1;
//            }
        }
    }

    class MyClass
    {
        private string _myString;

        public string MyString
        {
            get
            {
                if (_myString == null) throw new DataException("MyString is Null");
                return _myString;
            }
        }

        public MyClass(string myString)
        {
            _myString = myString;
        }

    }

}

【问题讨论】:

  • +1 提供了一个完整的例子。现在看看。
  • 为什么不在 Compare 方法中检查 null ?我在想,最好让框架抛出异常。
  • 因为我想冒泡到处理它的异常处理程序。

标签: c# .net


【解决方案1】:

Sort 方法周围有一个 try/catch 块,是的 - 并且该 catch 块捕获异常。换句话说,Sort 抛出一个异常并且你的 catch 块捕获它。它不会传播到Main 之外 - 所以“完成!”被打印出来了。

这正是我所期望的。在您的经验中,它以何种方式“未处理”?您是否期望Sort 不会抛出异常?它需要做一些事情来表明无法比较两个元素,这似乎是最合适的行动方案。

您的单元测试以何种方式失败?您是否故意向他们提供无效数据?您希望您的比较代码如何对无效数据做出反应?如果它应该忽略它(并返回基于另一个属性的比较),那么您应该主动检查该属性而不是让异常传播。在大多数情况下,如果这表明之前存在错误,我宁愿允许异常。

编辑:根据您的其他 cmets,听起来您正在做适当的事情,让异常冒泡 - 但尚不清楚您以何种方式看到异常未得到处理。

如果您在调试器中运行,它可能会在抛出异常时中断,但这并不意味着它不会被处理。尝试更改您的异常设置或在没有调试器的情况下运行。

编辑:是的,Sort 将捕获异常并抛出 InvalidOperationException - 但您可以使用该异常的 InnerException 属性来获取原始异常。不幸的是documentation 没有指定这个:(

【讨论】:

  • 看看编辑,我的 DataException 似乎在排序内部处理,并且从排序方法抛出 InvalidOperationException。
  • 无论如何要根据内部异常捕获?如果我必须为 InvalidOperationException 添加另一个异常处理程序,那将是代码异味
【解决方案2】:

例如,当它检查字符串“1”不等于 null 时。但它想比较“1”字符串和 null => 的长度,这是不可能的。

【讨论】:

  • 是的,PostMan 知道这一点 - 这是他感兴趣的异常抛出后发生的事情。
【解决方案3】:

我假设您使用 .Net Framework 4.0。新的东西是 NullRefenrenceException 不能再被捕获(类似于 OutOfMemory 异常)。

【讨论】:

  • 这根本不是真的。我刚刚尝试过,并设法毫无问题地抓住它。你是从哪里得到这个想法的?
  • (我刚刚在 .NET 4b2 中测试了 OP 的代码,它的行为方式完全相同。)
  • “相同方式”意味着无法捕获异常?还是什么?
  • 意味着异常被捕获,正如我所期望的那样,就像它在 .NET 3.5 中被捕获一样。
  • 看来你是对的。但是在这个网站的某个地方,我读到了关于新异常处理的信息。似乎那是虚假信息。
猜你喜欢
  • 2014-11-18
  • 2020-08-15
  • 2012-10-05
  • 1970-01-01
  • 2021-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-29
相关资源
最近更新 更多