2009-10-16 15 views
39

Wykonałem kilka testów jednostkowych na kodzie, które mogą rzucić pewną liczbę wyjątków w zależności od danych wejściowych. Więc próbowałem coś podobnego poniższy kod: (uproszczony dla przykładu)Dlaczego nie mogę złapać ogólnego wyjątku w języku C#?

static void Main(string[] args) 
    { 
     RunTest<ArgumentException>(); 
    } 

    static void RunTest<T>() where T : Exception, new() 
    { 
     try 
     { 
      throw new T(); 
      //throw new ArgumentException(); <-- Doesn't work either 

     } 
     catch (T tex) 
     { 
      Console.WriteLine("Caught passed in exception type"); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine("Caught general exception"); 
     } 
     Console.Read(); 
    } 

Ale to zawsze będzie drukować „Caught ogólny wyjątek”, tym catch (T tex) obsługi nigdy nie będzie działać. Nie ma znaczenia, czy rzucam T(), czy jawnie rzutuję ArgumentException(). Jakieś pomysły, dlaczego tak jest? Właściwie byłem trochę zaskoczony, że mogłem nawet użyć T w klauzuli catch, ale skoro jest to możliwe, czy nie powinno to działać? Lub przynajmniej dać ostrzeżenie/błąd kompilatora, który mówi, że ten handler nigdy nie zadziała?

Moje środowisko to Visual Studio 2008, a 3.5 to struktura docelowa.

AKTUALIZACJA: Próbowałem go teraz bezpośrednio z wiersza polecenia, a następnie wypisuje "Caught passed in exception type". Wygląda więc na to, że jest to ograniczone do działania z poziomu Visual Studio. Może cechą szczególną procesu hostingu Visual Studio?

+1

Właśnie testowałem go w LINQPad i wydrukowany Caught przeszedł w rodzaju wyjątku. Czy możesz podać więcej szczegółów na temat środowiska i wersji ramowej. –

+2

To interesujące. Uruchomiłem go jako aplikację konsolową w VS2008 i wydrukowano wyjątek Caught. –

+0

Działa również w aplikacji SnippetCompiler –

Odpowiedz

32

Dziwaczne zachowanie tutaj ...

Aplikacja konsoli VS2k8. Następujące:

try 
{ 
    throw new T(); 
} 
catch (T tex) 
{ 
    Console.WriteLine("Caught passed in exception type"); 
} 
catch (Exception ex) 
{ 
    Console.WriteLine("Caught general exception"); 
} 

powoduje "Caught ogólnym wyjątkiem".

Ale wyjmij (bezużytecznych) zmiennych ze sprawozdań połowowych:

try 
{ 
    throw new T(); 
} 
catch (T) 
{ 
    Console.WriteLine("Caught passed in exception type"); 
} 
catch (Exception) 
{ 
    Console.WriteLine("Caught general exception"); 
} 

skutkuje "Caught przeszedł w rodzaju wyjątków" !!!


Aktualizacja:

heheh ... Jego błąd: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=362422&wa=wsignin1.0

źródło? Tutaj. Why does catch(TException) handling block behaviour differ under the debugger after installing Visual Studio 2008?

2

Wydaje się, że najbardziej specyficzny typ wyjątku, gdy dany wybór między T a wyjątkiem jest wyjątkiem, a więc wywoływany jest wywoływacz.

Po prostu próbowałem tego (nie można tego zrobić w C# lub VB, ale edytowałem IL) i zmieniono drugą klauzulę catch, aby złapać Object Ex, a nie Exception Ex, iw takim przypadku pierwszy handler został trafiony.

Edit

Jak inni zwrócili uwagę, że to więcej wspólnego z prowadzeniem go w debugera niż określonego rodzaju

Powiązane problemy