2009-11-19 21 views
5

Por lo tanto, tengo una lista que contiene una clase personalizada, MiClase
MiClase tiene propiedades, que puede ser nulo (pero no están destinados a ser).

Cuando esta clase se ordena, utilizando un clasificador personalizado, donde el clasificador accede a esta propiedad nula y lanza una excepción, la excepción se considera no controlada, aunque hay un bloque try-catch alrededor del método de ordenación.

Ahora, por alguna razón, la excepción aún se escribe en la consola, que es lo que hace el controlador de excepciones.

Tengo una aplicación real con este mismo problema, lo que hace que mis pruebas de unidad fallen, aunque la excepción se maneje correctamente y no puedo explicar esto.
Excepción no controlada en la Lista Ordenar

Así que he adjuntado un código de muestra para explicarme mejor, ejecútelo desde VS.

Actualizado Código
Resultados:
System.InvalidOperationException
Error al comparar dos elementos de la matriz.
¡Hecho!

Parece que está manejando mi excepción personalizada, y lanzando la suya propia?

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

    } 

} 
+0

+1 para proporcionar un ejemplo completo. Mirándolo ahora. –

+0

¿por qué no verificas null en tu método de comparación? Sería mejor, estoy pensando, y luego permitir que el marco arroje una excepción. –

+0

Porque quiero saltar hasta mi controlador de excepciones, donde se maneja. – PostMan

Respuesta

3

Hay un bloque try/catch alrededor del método Sort, sí - y que bloque catch captura la excepción. En otras palabras, Sort arroja una excepción y tu bloque catch lo atrapa. Es no se propaga más allá de Main - entonces "¡Hecho!" está impreso.

Esto es exactamente lo que esperaría. ¿De qué manera es "no manejado" en tu experiencia? ¿Estabas esperando Sort para no lanzar la excepción? Necesita hacer algo para indicar la falla en la comparación de dos elementos, y este parece ser el curso de acción más apropiado.

¿De qué manera fallan las pruebas de su unidad? ¿Estás dándoles deliberadamente datos inválidos? ¿Cómo desea que su código de comparación reaccione a los datos no válidos? Si debe ignorarlo (y devolver una comparación basada en otra propiedad), entonces debe verificar activamente la propiedad en lugar de dejar que se propague una excepción. En la mayoría de los casos, prefiero permitir la excepción si esto indica que hay un error más temprano.

EDITAR: En base a sus otros comentarios, parece que está haciendo lo correcto, dejando que la excepción salga a relucir, pero no está claro de qué manera está viendo la excepción no procesada.

Si está ejecutando en el depurador, puede estar rompiendo la excepción lanzada, pero eso no significa que no se manejará. Intente cambiar su configuración de excepción o ejecutar sin el depurador.

EDITAR: Sí, Sort detectará la excepción y arrojará un InvalidOperationException, pero puede usar la propiedad InnerException de esa excepción para obtener la original. Es lamentable que el documentation no especifique esto :(

+0

Eche un vistazo a la edición, mi DataException parece manejarse dentro del género y una excepción InvalidOperationException del método de ordenación. – PostMan

+0

De todos modos para atrapar basado en la excepción interna? Sería un olor a código si tuviera que agregar otro manejador de excepciones solo para InvalidOperationException – PostMan

-1

Supongo que trabaja con .Net Framework 4.0.Lo nuevo es que una excepción NullRefenrenceException no se puede capturar más (similar a la excepción OutOfMemory).

+0

Eso no es cierto en absoluto. Lo acabo de probar y logré atraparlo sin problemas. ¿De dónde sacaste esa idea? –

+0

(Acabo de probar el código del OP en .NET 4b2 y se comporta exactamente de la misma manera.) –

+0

"¿El mismo modo", es decir, no puede detectar la excepción? ¿O que? –

0

Por ejemplo, cuando comprueba que la cadena "1" no es nula. Pero entonces quiere comparar longitudes de "1" cadena y nulo => que es imposible.

+0

Sí, PostMan es consciente de esto, es lo que sucede después de que se lanza la excepción que le interesa. –

Cuestiones relacionadas