2009-11-19 18 views
5

Quindi, ho una lista contenente una classe personalizzata, MyClass
MiaClasse ha proprietà, che può essere nullo (ma non sono destinate ad essere).

Quando questa classe viene ordinata, utilizzando un fascicolatore personalizzato, in cui il sorter accede a questa proprietà nulla e genera un'eccezione, l'eccezione viene considerata non gestita, anche se esiste un blocco try-catch attorno al metodo di ordinamento.

Ora per qualche motivo l'eccezione viene ancora scritta nella console, che è ciò che sta facendo il gestore delle eccezioni.

Ho una vera applicazione con questo stesso problema, causando il fallimento dei test dell'unità, anche se l'eccezione viene gestita correttamente e non posso spiegarlo.
eccezione non gestita in Lista Sort

Quindi ho allegato qualche codice di esempio per spiegarmi meglio, eseguirlo da VS.

Aggiornato Codice
Risultati:
System.InvalidOperationException
Impossibile confrontare due elementi dell'array.
Fatto!

Quindi sembra gestire l'eccezione personalizzata e lanciare il proprio?

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 per fornire un esempio completo. Guardandolo ora. –

+0

perché non controlli nulla nel tuo metodo di confronto? Sarebbe meglio, sto pensando, quindi consentire al framework di lanciare un'eccezione. –

+0

Perché voglio presentarmi al gestore delle eccezioni, dove viene gestito. – PostMan

risposta

3

C'è un blocco try/catch intorno al metodo di Sort, sì - e questo blocco catch cattura l'eccezione. In altre parole, Sort genera un'eccezione e il blocco catch lo rileva. È non propagare oltre Main - così "Fatto!" è stampato

Questo è esattamente quello che mi aspetterei. In che modo è "non gestito" nella tua esperienza? Ti aspettavi che Sort non lanciasse l'eccezione? Ha bisogno di fare qualcosa per indicare l'incapacità di confrontare due elementi, e questa sembra essere la linea d'azione più appropriata.

In che modo falliscono i test dell'unità? Stai deliberatamente dando loro dati non validi? Come si desidera che il codice di confronto reagisca a dati non validi? Se dovrebbe ignorarlo (e restituire un confronto basato su un'altra proprietà), allora dovresti controllare attivamente la proprietà piuttosto che far propagare un'eccezione. Nella maggior parte dei casi preferisco consentire l'eccezione se questo indica che c'è un bug in precedenza però.

MODIFICA: in base ai tuoi altri commenti, sembra che tu stia facendo la cosa giusta, facendo esplodere l'eccezione - ma non è chiaro in che modo stai vedendo che l'eccezione non viene gestita.

Se si sta eseguendo nel debugger, è possibile che si stia verificando l'eccezione generata, ma ciò non significa che non verrà gestito. Prova a modificare le impostazioni delle eccezioni o esegui senza il debugger.

EDIT: Sì, Sort cattura l'eccezione e genera un InvalidOperationException invece - ma è possibile utilizzare la proprietà InnerException di tale eccezione per entrare in possesso di quella originale. È spiacevole che lo documentation non specifichi questo :(

+0

Dai un'occhiata alla modifica, la mia DataException sembra essere gestita all'interno dell'ordinamento e un tiro InvalidOperationException dal metodo sort. – PostMan

+0

Ad ogni modo catturare in base all'eccezione interna? Sarà un odore di codice se devo aggiungere un altro gestore di eccezioni solo per InvalidOperationException – PostMan

-1

Suppongo che tu lavori con .Net Framework 4.0.La novità è che non è possibile catturare una NullRefenrenceException (simile all'eccezione OutOfMemory).

+0

Questo non è affatto vero. L'ho appena provato e sono riuscito a catturarlo senza problemi. Dove hai preso quell'idea? –

+0

(Ho appena testato il codice dell'OP in .NET 4b2 e si comporta esattamente nello stesso modo.) –

+0

"Stesso modo" che significa impossibile rilevare l'eccezione? O cosa? –

0

Ad esempio, quando verifica che la stringa "1" non sia uguale a null. Ma vuole quindi confrontare lunghezze di "1" stringa e null => che è impossibile.

+0

Sì, PostMan ne è consapevole, è ciò che accade dopo che è stata lanciata l'eccezione a cui è interessato. –

Problemi correlati