2015-02-08 14 views
13

Ich möchte das throw Schlüsselwort überlasten, um eine Klasse zu fangen, die von Exception erbt und es einige Logging und andere Sachen vor dem eigentlichen Wurf zu tun haben. Ist das möglich? Oder muss ich eine normale Funktion verwenden?Kann ich das throw-Schlüsselwort überladen?

Ich habe versucht:

public class cSilException : Exception 
    { 
     private string m_strMsg; 

     public override void throw(cSilException ex) 
     { 

     } 
... 
... 
} 
+6

Was nutzt es? –

+2

Schlüsselwörter sind weder übersteuerbar noch überladbar. –

+0

Auch wenn Sie throw überschreiben könnten, könnten Sie ein unerwartetes Ergebnis der zugrunde liegenden Bibliotheken sehen. :) – eandersson

Antwort

21

Was möchten Sie ist ein Konstruktor Ihre Ausnahme tun fügen und tun, was Sie in diesem Konstruktor tun müssen.

public class cSilException : Exception 
{ 
    //constructor 
    public cSilException() 
    { 
     // do stuff here 
    } 
} 

Ihre Vorstellung von „Überlastung des Schlüsselwort throw“ war ganz, äh, wie ich es ausdrücken, psychedelisch.

Natürlich ist es am besten, dies zu vermeiden, wenn Sie vorhaben, Dinge wie das Protokollieren zu tun. Alois Kraus hat eine weitere Antwort mit einem sehr guten Vorschlag gepostet.

+9

Beachten Sie, dass Sie, wenn Sie die Ausnahme im Ctor protokollieren, sehr wahrscheinlich protokollierte Ausnahmen sehen, die nie tatsächlich ausgelöst wurden - nur instanziiert. Für Protokollierungszwecke ist es besser, eine Erweiterungs-/Hilfsmethode 'LogAndThrow' zu verwenden. – SimpleVar

+2

Außerdem können Ausnahmen abgefangen und erneut ausgelöst werden. In diesem Fall wird nur eine Protokollnachricht angezeigt. –

+1

Und das funktioniert auch in C++. Genau so. –

2

Sie können nicht throw überlasten es ist ein integraler Bestandteil der Sprache (kein Mitglied einer Klasse)

Wenn Sie eine bestimmte Ausnahme behandeln wollen, sollten Sie diese Ausnahme catch:

try 
{ 
    // your code, which throws some exceptions 
} 
catch(cSilException csEx) 
{ 
    // handle csEx 
    throw; // rethrow this exception 
} 
catch(Exception ex) 
{ 
    // handle all other exceptions 
} 

Dieser Code fängt die spezielle Ausnahme cSilException in einem anderen Codeblock ab als alle anderen Ausnahmen.

2

Suchen Sie nach Methoden und Membern der Klasse Exception. Sie können Konstruktor für cSilException wie diese

public cSilException(string message) 
{ 
    Message = message; 
} 

und als in catch (cSilException ex)Console.WriteLine(ex.Message);

7

definiere ich würde innerhalb der Ausnahme Konstruktor Anmeldung etwas nicht empfehlen, da es die einzige Verantwortung Prinzip verstößt und ist ein schlechtes Design berücksichtigt. Außerdem bedeutet die Tatsache, dass eine Ausnahme erstellt wurde, nicht unbedingt, dass sie ausgelöst wurde, und außerdem können Ausnahmen abgefangen und erneut ausgelöst werden - diese Dinge können zu falschen Protokollierungsnachrichten führen.

Stattdessen können Sie einen anwendungsweiten Exception-Handler verwenden, der Ausnahmen gemäß Ihrer vordefinierten Richtlinie behandelt. Zum Beispiel können Sie sich die Enterprise Library Exception Handling Block und speziell this section ansehen.

23

Registrieren Sie das Ereignis AppDomain.FirstChanceException. Dort erhalten Sie alle Ausnahmen, bevor die tatsächlich geworfen werden. Im Event-Handler können Sie nach Ihrem exception suchen und die erforderliche Protokollierung durchführen.

Keine Magie und kein schlechtes Design.

class Program 
{ 
    static void Main(string[] args) 
    { 
     AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException; 
     DoBadThings(); 
    } 

    private static void DoBadThings() 
    { 
     DoOneLevelBelow(); 
    } 

    private static void DoOneLevelBelow() 
    { 

     for(int i=0;i<10;i++) 
     { 
      try 
      { 
       if (i == 5) 
       { 
        var invalidCast = (string)((object)i); 
       } 
       else 
       { 
        throw new InvalidTimeZoneException(); 
       } 
      } 
      catch 
      { 

      } 
     } 
    } 

    static void CurrentDomain_FirstChanceException(object sender, System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs e) 
    { 
     if(e.Exception is InvalidCastException) 
     { 
      LogInvalidCast((InvalidCastException)e.Exception); 
     } 
    } 

    private static void LogInvalidCast(InvalidCastException invalidCastException) 
    { 
     Console.WriteLine("Got Invalid cast: {0}", invalidCastException); 
    } 

Diese führen wird:

Got ungültig Besetzung: System.InvalidCastException: Das Objekt vom Typ "System.Int32" kann nicht konvertiert werden, um "System.String". bei ThrowTest.Program.DoOneLevelBelow() in d: \ Media \ Blog \ ThrowTest \ Program.cs: Linie 31.

Bitte beachten Sie, da Sie die Ausnahme erhalten, bevor der Stapel abgewickelt wird Sie nur die Methode sehen, wo es geschah aber nicht die Aufrufmethoden, da der Stapel noch nicht abgewickelt wurde. Wenn Sie den kompletten Call-Stack haben möchten, können Sie Environment.StackTrace verwenden, um alle Stack-Frames zu erhalten.

Verwandte Themen