2011-01-25 12 views
57

Jakie są najlepsze w branży sprawdzone metody wdrażania niestandardowych wyjątków w języku C#?Jakie są najlepsze w branży sprawdzone metody wdrażania niestandardowych wyjątków w języku C#?

Sprawdziłem Google i istnieje wiele zaleceń, ale nie wiem, które z nich są bardziej wiarygodne.

Jeśli ktoś ma jakieś linki do artykułów autorytatywnych, to też byłoby pomocne.

+1

podobne do http://bit.ly/hVTSgp polecam że zawężenia tematu poprzez dalsze wyjaśnienia, co szukasz. –

+0

Mój szef chce, żebym utworzył niestandardową klasę wyjątków dla napisanego przeze mnie programu, abyśmy mogli łatwo zidentyfikować konkretne błędy. Będą to takie rzeczy jak: Brak danych w konkretnej komórce programu Excel, wyjątki poza wyjątkami (mogą używać standardu), dane nie są przesyłane w określonej kolejności itp. –

+7

Wygląda na to, że używasz wyjątków do obsługi przepływów logiki biznesowej - oczekiwanych w miarę możliwości należy rozwiązywać problemy bez stosowania wyjątków. – cjk

Odpowiedz

64

Norma dla tworzenia niestandardowych wyjątków jest czerpanie z Exception. Następnie możesz wprowadzić własne właściwości/metody i przeładowane konstruktory (jeśli dotyczy).

Oto podstawowy przykład niestandardowego ConnectionFailedException, który przyjmuje dodatkowy parametr, który jest specyficzny dla typu wyjątku.

[Serializable] 
public class ConnectionFailedException : Exception 
{ 
    public ConnectionFailedException(string message, string connectionString) 
     : base(message) 
    { 
     ConnectionString = connectionString; 
    } 

    public string ConnectionString { get; private set; } 
} 

W zastosowaniu mogłoby być stosowane w sytuacjach, w których aplikacja próbuje połączyć się z bazy danych, np

try 
{ 
    ConnectToDb(AConnString); 
} 
catch (Exception ex) 
{ 
    throw new ConnectionFailedException(ex.Message, AConnString); 
} 

To do ciebie, aby następnie obsłużyć ConnectionFailedException na wyższym poziomie (jeśli dotyczy)

Również spojrzeć na Designing Custom Exceptions i Custom Exceptions

+2

Fajne dzięki @ James ... bardzo pomocne – scarpacci

+0

Dlaczego nie tylko wyjątki typu ConnectionFailedException są bardziej celowe? –

+0

@Anar przykład pokazuje * jak * podnosisz 'ConnectionFailedException' oczekiwanie, że możesz złapać to wyżej na stosie wywołań. Można złapać bardziej znaczący wyjątek podniesiony z 'ConnectToDb' zamiast ogólnego' Exception', jednak był to tylko do celów demonstracyjnych. – James

8

Oto kod, aby utworzyć niestandardowy wyjątek:

using System; 
using System.Runtime.Serialization; 

namespace YourNamespaceHere 
{ 
    [Serializable()] 
    public class YourCustomException : Exception, ISerializable 
    { 
     public YourCustomException() : base() { } 
     public YourCustomException(string message) : base(message) { } 
     public YourCustomException(string message, System.Exception inner) : base(message, inner) { } 
     public YourCustomException(SerializationInfo info, StreamingContext context) : base(info, context) { } 
    } 
} 

Zobacz także: http://www.capprime.com/software_development_weblog/2005/06/16/CreatingACustomExceptionClassInC.aspx

+0

FWIW - jest to prawie dokładnie to, co wynika z użycia fragmentu 'wyjątku' zawartego w Visual Studio. –

+0

Doskonały. Napisałem post na blogu w 2005 roku, ale myślę, że były pewne wskazówki od Microsoftu, na których oparłem je i wygląda na to, że wskazówki zostały skodyfikowane w VS za pomocą urywka. –

0

Używam niestandardowych wyjątków do informowania o charakterze błędu.

Na przykład, lubię używać frameworka "ArgumentNullException" do sprawdzania argumentów. Później, kiedy widzę ten błąd albo w debugerze, albo w dzienniku błędów, od razu znam naturę błędu bez dalszego czytania.

Drugi koniec spektrum to wyjątek InvalidOperationException, który może oznaczać praktycznie wszystko.

Alternatywą dla niestandardowych wyjątków są szczegółowe komunikaty o błędach. Jest to ok, ale tworzenie niestandardowego wyjątku, takiego jak ConnectionFailed, jest bardziej znaczące. Wtedy sama wiadomość może podać więcej szczegółów.

Podczas tworzenia takich niestandardowych wyjątków nie dodaję żadnych nowych właściwości. Powodem tego jest to, że jeśli masz rejestr błędów, chcesz, aby działał na wszystkie wyjątki. Jeśli dodasz specjalną właściwość, rejestrator błędów zignoruje ją. Na przykład, jeśli używasz MSTest, po uruchomieniu testu i nie powiedzie się, właściwości niestandardowe nie są wyświetlane. Ale jeśli pozostaniesz z właściwością Message klasy baseclass, będzie to wyglądało dobrze.

Więc subclassing jest bardzo prosta:

public class NavigationException : Exception{ 
    public NavigationException() {} 
    public NavigationException(string msg) : base(msg) {} 
    public NavigationException(string msg, Exception inner) : base(msg, inner) {} 
} 

To jest bardzo proste, działa z każdym rejestratorem błędów, a kiedy widzę go, wiem, że był to problem nawigacji i mogę wyświetlić szczegóły w razie potrzeby .

Greg

Powiązane problemy