2009-05-26 14 views
8

Czy możliwe jest zgłoszenie wyjątku (może to być wyjątek) z niestandardowym śledzeniem stosu?Wyrzucanie wyjątków z niestandardowym śledzeniem stosu

Jako konkretny przykład: powiedzmy, że mam zestaw niewielkich metod statycznych, które mogą generować wyjątki. Jednak chciałbym, aby wyjątek wyglądał na pochodzący z poprzedniej metody zamiast metody użyteczności (chcę zignorować pierwszą ramkę śledzenia).

Odpowiedz

3

Przenoszenie się ze śladami stosu naprawdę nie brzmi jak dobry pomysł, nawet jeśli jest to możliwe (wątpię w to). Powiedz mi, dlaczego i tak chcesz to robić? Sama platforma .NET (BCL) często używa statycznych metod użyteczności do zgłaszania wyjątków w sposób, który sugerujesz (ThrowHelper jest jego nazwa w co najmniej niektórych częściach frameworka), i na pewno ukryje cokolwiek w śladzie stosu.

Oto przykład ślad stosu z testu po prostu biegł:

 
    at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource) 
    at System.ThrowHelper.ThrowArgumentOutOfRangeException() 
    at System.Collections.Generic.List`1.get_Item(Int32 index) 
    at HelloWorld.Program.Main(String[] args) in C:\...\Program.cs:line 23 
    at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args) 
    at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 
    at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
    at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
    at System.Threading.ThreadHelper.ThreadStart() 

Jak widać, plc wykorzystuje metodę ThrowArgumentOutOfRangeException, i to wyraźnie widoczne w ślad stosu. Jeśli chcesz oznaczyć metodę pomocnika za pomocą atrybutu DebuggerNonUserCode, to wydaje mi się to wystarczająco dobre (chociaż nie jest to zrobione w BCL).

+0

Przypuszczam, że masz rację. Głównym powodem, dla którego chciałem to zrobić, było "spasowanie" debugowania tych wyjątków podczas rzucania. Jednak myślę, że lepszym sposobem na osiągnięcie tego, co chcę jest użycie [DebuggerNonUserCode] atrybut na moje metody. –

+0

Tak, dokładnie widzę, skąd przybywasz. Metody helpera .NET nie używają atrybutu DebuggerNonUserCode, ale wydaje mi się to sensownym pomysłem. – Noldorin

12

Właściwość StackTrace jest wirtualna - utwórz własną klasę Exception i zwróć właściwość, co chcesz.

+0

Zrobiłbym to, ale wolałbym wyrzucić oryginalny typ wyjątku. I nie chcę przekazywać tego jako wewnętrznego wyjątku. –

+0

Możliwe jest dziedziczenie własnego wyjątku z wielu (być może wszystkich) normalnych wyjątków, więc niestandardowy wyjątek z niestandardowym obiektem StackTrace może zostać przechwycony przez blok catch dla standardowego wyjątku. – supercat

+0

Powód, dla którego to nie działa zbyt dobrze, jest taki, że podstawowa implementacja ToString w Exception nie używa właściwości StackTrace, wywołuje metodę prywatną GetStackTrace (co wywołuje właściwość StackTrace), więc oznacza to, że przesłonięcie jest bezużyteczne w odniesieniu do domyślnego zachowania. Bardzo niefortunna decyzja projektowa, która na pewno nie może w tym momencie ulec zmianie. – MarkPflug

Powiązane problemy