C# 列表排序中未处理的异常

C# 列表排序中未处理的异常,c#,.net,C#,.net,因此,我有一个包含自定义类的列表,MyClass MyClass具有属性,这些属性可以为null(但并不意味着为null) 使用自定义分类器对此类进行排序时,分类器访问此null属性并引发异常,即使排序方法周围有try-catch块,该异常仍被视为未处理。 现在,由于某种原因,异常仍然会写入控制台,这就是异常处理程序正在执行的操作。 我有一个真实的应用程序存在同样的问题,导致我的单元测试失败,即使异常处理正确,我也无法解释这一点。 因此,为了更好地解释自己,我附加了一些示例代码,从VS运行此代码

因此,我有一个包含自定义类的列表,MyClass
MyClass具有属性,这些属性可以为null(但并不意味着为null)

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

现在,由于某种原因,异常仍然会写入控制台,这就是异常处理程序正在执行的操作。

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

因此,为了更好地解释自己,我附加了一些示例代码,从VS运行此代码。

更新的代码
结果:
系统无效操作异常
无法比较数组中的两个元素。
完成了
所以它似乎在处理我的自定义异常,并抛出自己的异常

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

    }

}
使用系统;
使用System.Collections.Generic;
使用系统数据;
命名空间TestSortException
{
班级计划
{
静态void Main()
{
尝试
{
变量列表=新列表
{
新MyClass(“1”),
新MyClass(空),
新MyClass(“fdsfsdf”)
};
Sort(新的MyClassSorter());
}
捕获(例外e)
{
Console.WriteLine(e.GetType());
控制台写入线(e.Message);
}
控制台。WriteLine(“完成!”);
Console.ReadLine();
}
}
类别MyClassSorter:IComparer
{
公共整数比较(MyClass x,MyClass y)
{
//试一试
//            {
if(x.MyString==y.MyString)
返回0;
//未处理???此处出现异常
if(x.MyString.Length>y.MyString.Length)
返回1;
返回-1;
//            }
//捕获(例外)
//            {
//返回-1;
//            }
}
}
类MyClass
{
私有字符串_myString;
公共字符串MyString
{
得到
{
如果(_myString==null)抛出新的DataException(“myString为null”);
返回我的字符串;
}
}
公共MyClass(字符串myString)
{
_myString=myString;
}
}
}

排序方法周围有一个try/catch块,是的-catch块捕获异常。换句话说,
Sort
抛出一个异常,您的catch块将捕获它。它不会在
Main
之外传播,因此会打印“完成!”

这正是我所期望的。在你的经历中,它以什么方式“未处理”?您是否希望
Sort
不会引发异常?它需要做一些事情来表明比较两个元素的失败,而这似乎是最合适的做法

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

编辑:根据你的其他评论,听起来你在做适当的事情,让异常冒泡——但不清楚你是以什么方式看到异常不被处理的

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


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

我假设您使用.Net Framework 4.0。新的情况是,无法再捕获NullRefenrenceException(类似于OutOfMemory异常)。

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

+1提供了一个完整的示例。现在来看一下。为什么不在比较方法中检查null?我想,这样会更好,然后允许框架抛出一个异常。因为我想冒泡到我的异常处理程序,在那里处理它。这根本不是真的。我刚刚尝试了它,并设法抓住它没有问题。你是从哪里得到这个想法的?(我刚刚在.NET 4b2中测试了OP的代码,它的行为完全相同。)“同样的方式”意思是无法捕获异常?或者什么?意思是异常被捕获,正如我预期的那样,就像在.NET 3.5中捕获的一样。看起来你是对的。但是在这个网站上的某个地方,我读到了有关新异常处理的信息。这似乎是错误的信息。是的,邮递员知道这一点-这是异常发生后发生的事情他感兴趣的抛出。看看编辑,我的DataException似乎是在sort中处理的,而InvalidOperationException是从sort方法中抛出的。是否要基于内部异常捕获?如果我必须为InvalidOperationException添加另一个异常处理程序,这将是一种代码气味