Exception.Data Eigenschaft

Definition

Ruft eine Auflistung von Schlüssel-Wert-Paaren ab, die zusätzliche benutzerdefinierte Informationen zur Ausnahme bereitstellen.

public:
 virtual property System::Collections::IDictionary ^ Data { System::Collections::IDictionary ^ get(); };
public virtual System.Collections.IDictionary Data { get; }
member this.Data : System.Collections.IDictionary
Public Overridable ReadOnly Property Data As IDictionary

Eigenschaftswert

IDictionary

Ein Objekt, das die IDictionary-Schnittstelle implementiert und eine Auflistung benutzerdefinierter Schlüssel-Wert-Paare enthält. Der Standard ist eine leere Auflistung.

Beispiele

Im folgenden Beispiel wird veranschaulicht, wie Mithilfe der Data Eigenschaft Informationen hinzugefügt und abgerufen werden.

using namespace System;
using namespace System::Collections;

void NestedRunTest( bool displayDetails ); // forward declarations
void NestedRoutine1( bool displayDetails );
void NestedRoutine2( bool displayDetails );
void RunTest( bool displayDetails );

int main()
{
   Console::WriteLine("\nException with some extra information..." );
   RunTest(false);
   Console::WriteLine("\nException with all extra information..." );
   RunTest(true);
}

void RunTest( bool displayDetails )
{
   try
   {
      NestedRoutine1( displayDetails );
   }
   catch ( Exception^ e ) 
   {
      Console::WriteLine( "An exception was thrown." );
      Console::WriteLine( e->Message );
      if ( e->Data != nullptr )
      {
         Console::WriteLine( "  Extra details:" );

         for each (DictionaryEntry de in e->Data)
            Console::WriteLine("    Key: {0,-20}      Value: {1}", 
                               "'" + de.Key->ToString() + "'", de.Value);
      }
   }
}

void NestedRoutine1( bool displayDetails )
{
   try
   {
      NestedRoutine2( displayDetails );
   }
   catch ( Exception^ e ) 
   {
      e->Data[ "ExtraInfo" ] = "Information from NestedRoutine1.";
      e->Data->Add( "MoreExtraInfo", "More information from NestedRoutine1." );
      throw;
   }
}

void NestedRoutine2( bool displayDetails )
{
   Exception^ e = gcnew Exception( "This statement is the original exception message." );
   if ( displayDetails )
   {
      String^ s = "Information from NestedRoutine2.";
      int i = -903;
      DateTime dt = DateTime::Now;
      e->Data->Add( "stringInfo", s );
      e->Data[ "IntInfo" ] = i;
      e->Data[ "DateTimeInfo" ] = dt;
   }

   throw e;
}

/*
This example produces the following results:

Exception with some extra information...
An exception was thrown.
This statement is the original exception message.
  Extra details:
    The key is 'ExtraInfo' and the value is: Information from NestedRoutine1.
    The key is 'MoreExtraInfo' and the value is: More information from NestedRoutine1.

Exception with all extra information...
An exception was thrown.
This statement is the original exception message.
  Extra details:
    The key is 'stringInfo' and the value is: Information from NestedRoutine2.
    The key is 'IntInfo' and the value is: -903
    The key is 'DateTimeInfo' and the value is: 11/26/2002 2:12:58 PM
    The key is 'ExtraInfo' and the value is: Information from NestedRoutine1.
    The key is 'MoreExtraInfo' and the value is: More information from NestedRoutine1.
*/
// This example demonstrates the Exception.Data property.
using System;
using System.Collections;

class Sample
{
   public static void Main()
   {
      Console.WriteLine("\nException with some extra information...");
      RunTest(false);
      Console.WriteLine("\nException with all extra information...");
      RunTest(true);
   }

   public static void RunTest(bool displayDetails)
   {
      try {
         NestedRoutine1(displayDetails);
      }
      catch (Exception e) {
         Console.WriteLine("An exception was thrown.");
         Console.WriteLine(e.Message);
         if (e.Data.Count > 0) {
            Console.WriteLine("  Extra details:");
            foreach (DictionaryEntry de in e.Data)
               Console.WriteLine("    Key: {0,-20}      Value: {1}",
                                 "'" + de.Key.ToString() + "'", de.Value);
         }
      }
   }

   public static void NestedRoutine1(bool displayDetails)
   {
      try {
         NestedRoutine2(displayDetails);
      }
      catch (Exception e) {
         e.Data["ExtraInfo"] = "Information from NestedRoutine1.";
         e.Data.Add("MoreExtraInfo", "More information from NestedRoutine1.");
         throw;
      }
   }

   public static void NestedRoutine2(bool displayDetails)
   {
      Exception e = new Exception("This statement is the original exception message.");
      if (displayDetails) {
         string s = "Information from NestedRoutine2.";
         int i = -903;
         DateTime dt = DateTime.Now;
         e.Data.Add("stringInfo", s);
         e.Data["IntInfo"] = i;
         e.Data["DateTimeInfo"] = dt;
      }
      throw e;
   }
}
// The example displays the following output:
//    Exception with some extra information...
//    An exception was thrown.
//    This statement is the original exception message.
//      Extra details:
//        Key: 'ExtraInfo'               Value: Information from NestedRoutine1.
//        Key: 'MoreExtraInfo'           Value: More information from NestedRoutine1.
//
//    Exception with all extra information...
//    An exception was thrown.
//    This statement is the original exception message.
//      Extra details:
//        Key: 'stringInfo'              Value: Information from NestedRoutine2.
//        Key: 'IntInfo'                 Value: -903
//        Key: 'DateTimeInfo'            Value: 7/29/2013 10:50:13 AM
//        Key: 'ExtraInfo'               Value: Information from NestedRoutine1.
//        Key: 'MoreExtraInfo'           Value: More information from NestedRoutine1.
// This example demonstrates the Exception.Data property.
open System
open System.Collections

let nestedRoutine2 displayDetails =
    let e = Exception "This statement is the original exception message."
    if displayDetails then
        let s = "Information from nestedRoutine2."
        let i = -903
        let dt = DateTime.Now
        e.Data.Add("stringInfo", s)
        e.Data["IntInfo"] <- i
        e.Data["DateTimeInfo"] <- dt
    raise e

let nestedRoutine1 displayDetails =
    try
        nestedRoutine2 displayDetails
    with e ->
        e.Data["ExtraInfo"] <- "Information from nestedRoutine1."
        e.Data.Add("MoreExtraInfo", "More information from nestedRoutine1.")
        reraise ()

let runTest displayDetails =
    try
        nestedRoutine1 displayDetails
    with e ->
        printfn "An exception was thrown."
        printfn $"{e.Message}"
        if e.Data.Count > 0 then
            printfn "  Extra details:"
            for de in e.Data do
                let de = de :?> DictionaryEntry
                printfn $"""    Key: {"'" + de.Key.ToString() + "'",-20}      Value: {de.Value}"""

printfn "\nException with some extra information..."
runTest false
printfn "\nException with all extra information..."
runTest true

   
// The example displays the following output:
//    Exception with some extra information...
//    An exception was thrown.
//    This statement is the original exception message.
//      Extra details:
//        Key: 'ExtraInfo'               Value: Information from NestedRoutine1.
//        Key: 'MoreExtraInfo'           Value: More information from NestedRoutine1.
//
//    Exception with all extra information...
//    An exception was thrown.
//    This statement is the original exception message.
//      Extra details:
//        Key: 'stringInfo'              Value: Information from NestedRoutine2.
//        Key: 'IntInfo'                 Value: -903
//        Key: 'DateTimeInfo'            Value: 7/29/2013 10:50:13 AM
//        Key: 'ExtraInfo'               Value: Information from NestedRoutine1.
//        Key: 'MoreExtraInfo'           Value: More information from NestedRoutine1.
Imports System.Collections

Module Example
   Public Sub Main()
      Console.WriteLine()
      Console.WriteLine("Exception with some extra information...")
      RunTest(False)
      Console.WriteLine()
      Console.WriteLine("Exception with all extra information...")
      RunTest(True)
   End Sub

   Public Sub RunTest(displayDetails As Boolean)
      Try
         NestedRoutine1(displayDetails)
      Catch e As Exception
         Console.WriteLine("An exception was thrown.")
         Console.WriteLine(e.Message)
         If e.Data.Count > 0 Then
            Console.WriteLine("  Extra details:")
            For Each de As DictionaryEntry In e.Data
               Console.WriteLine("    Key: {0,-20}      Value: {1}",
                                 "'" + de.Key.ToString() + "'", de.Value)
            Next
         End If 
      End Try 
   End Sub 

   Public Sub NestedRoutine1(displayDetails As Boolean)
      Try
         NestedRoutine2(displayDetails)
      Catch e As Exception
         e.Data("ExtraInfo") = "Information from NestedRoutine1."
         e.Data.Add("MoreExtraInfo", "More information from NestedRoutine1.")
         Throw e
      End Try 
   End Sub

   Public Sub NestedRoutine2(displayDetails As Boolean)
      Dim e As New Exception("This statement is the original exception message.")
      If displayDetails Then 
         Dim s As String = "Information from NestedRoutine2." 
         Dim i As Integer = -903
         Dim dt As DateTime = DateTime.Now
         e.Data.Add("stringInfo", s)
         e.Data("IntInfo") = i
         e.Data("DateTimeInfo") = dt
      End If 
      Throw e
   End Sub 
End Module
' This example displays the following output: 
'    Exception with some extra information...
'    An exception was thrown.
'    This statement is the original exception message.
'      Extra details:
'        Key: 'ExtraInfo'               Value: Information from NestedRoutine1.
'        Key: 'MoreExtraInfo'           Value: More information from NestedRoutine1.
'    
'    Exception with all extra information...
'    An exception was thrown.
'    This statement is the original exception message.
'      Extra details:
'        Key: 'stringInfo'              Value: Information from NestedRoutine2.
'        Key: 'IntInfo'                 Value: -903
'        Key: 'DateTimeInfo'            Value: 7/29/2013 10:50:13 AM
'        Key: 'ExtraInfo'               Value: Information from NestedRoutine1.
'        Key: 'MoreExtraInfo'           Value: More information from NestedRoutine1.

Hinweise

Verwenden Sie das System.Collections.IDictionary von der Data Eigenschaft zurückgegebene Objekt, um zusätzliche Informationen zu speichern und abzurufen, die für die Ausnahme relevant sind. Die Informationen sind in Form einer beliebigen Anzahl von benutzerdefinierten Schlüssel-/Wertpaaren vorhanden. Die Schlüsselkomponente jedes Schlüssel-/Wertpaars ist in der Regel eine identifizierende Zeichenfolge, während die Wertkomponente des Paares ein beliebiger Objekttyp sein kann.

Sicherheit für Schlüssel-/Wertpaare

Die schlüssel-wert-Paare, die in der von der Data Eigenschaft zurückgegebenen Auflistung gespeichert sind, sind nicht sicher. Wenn Ihre Anwendung eine geschachtelte Reihe von Routinen aufruft und jede Routine Ausnahmehandler enthält, enthält der resultierende Aufrufstapel eine Hierarchie dieser Ausnahmehandler. Wenn eine Routine auf niedrigerer Ebene eine Ausnahme auslöst, kann jeder Ausnahmehandler auf oberster Ebene in der Aufrufstapelhierarchie die in der Auflistung gespeicherten Schlüssel-/Wertpaare durch einen anderen Ausnahmehandler lesen und/oder ändern. Dies bedeutet, dass die Informationen in den Schlüssel-Wert-Paaren nicht vertraulich sind und ihre Anwendung ordnungsgemäß funktioniert, wenn die Informationen in den Schlüssel-Wert-Paaren beschädigt sind.

Schlüsselkonflikte

Ein Schlüsselkonflikt tritt auf, wenn unterschiedliche Ausnahmehandler denselben Schlüssel angeben, um auf ein Schlüssel/Wertpaar zuzugreifen. Achten Sie beim Entwickeln Ihrer Anwendung darauf, dass die Folge eines Schlüsselkonflikts ist, dass Ausnahmehandler auf niedrigerer Ebene versehentlich mit Ausnahmehandlern höherer Ebene kommunizieren können, und diese Kommunikation kann subtile Programmfehler verursachen. Wenn Sie jedoch vorsichtig sind, können Sie wichtige Konflikte verwenden, um Ihre Anwendung zu verbessern.

Vermeiden von Schlüsselkonflikten

Vermeiden Sie Schlüsselkonflikte, indem Sie eine Benennungskonvention einführen, um eindeutige Schlüssel für Schlüssel-/Wertpaare zu generieren. Beispielsweise kann eine Benennungskonvention einen Schlüssel liefern, der aus dem durch Punkt getrennten Namen Ihrer Anwendung besteht, der Methode, die ergänzende Informationen für das Paar und einen eindeutigen Bezeichner bereitstellt.

Angenommen, zwei Anwendungen mit dem Namen "Produkte" und "Lieferanten" haben jeweils eine Methode namens "Sales". Die Vertriebsmethode in der Anwendung "Produkte" stellt die Identifikationsnummer (die Lagerhaltungseinheit oder SKU) eines Produkts bereit. Die Vertriebsmethode in der Lieferantenanwendung stellt die Identifikationsnummer oder SID eines Lieferanten bereit. Folglich liefert die Benennungskonvention für dieses Beispiel die Schlüssel "Products.Sales.SKU" und "Supplier.Sales.SID".

Exploiting Key Conflicts

Exploit key conflicts by using the presence of one or more special, prearranged keys to control processing. Angenommen, in einem Szenario fängt der Ausnahmehandler der höchsten Ebene in der Aufrufstapelhierarchie alle Ausnahmen ab, die von Ausnahmehandlern auf niedrigerer Ebene ausgelöst werden. Wenn ein Schlüssel-Wert-Paar mit einem speziellen Schlüssel vorhanden ist, formatiert der Ausnahmehandler auf hoher Ebene die verbleibenden Schlüssel-Wert-Paare im IDictionary Objekt in einer nicht standardmäßigen Weise. Andernfalls werden die verbleibenden Schlüssel-/Wertpaare normal formatiert.

Nehmen wir nun an, in einem anderen Szenario wird der Ausnahmehandler auf jeder Ebene der Aufrufstapelhierarchie vom nächsten Ausnahmehandler auf niedrigerer Ebene ausgelöst. Darüber hinaus weiß jeder Ausnahmehandler, dass die von der Eigenschaft zurückgegebene Auflistung eine Reihe von Schlüssel-Wert-Paaren enthält, auf die Data mit einem vordefinierten Satz von Schlüsseln zugegriffen werden kann.

Jeder Ausnahmehandler verwendet den vordefinierten Satz von Schlüsseln, um die Wertkomponente des entsprechenden Schlüssel/Wertpaars mit Informationen zu aktualisieren, die für diesen Ausnahmehandler eindeutig sind. Nachdem der Updatevorgang abgeschlossen ist, löst der Ausnahmehandler die Ausnahme auf den nächsten Ausnahmehandler auf höherer Ebene aus. Schließlich greift der Ausnahmehandler der höchsten Ebene auf die Schlüssel-Wert-Paare zu und zeigt die konsolidierten Updateinformationen aller Ausnahmehandler auf niedrigerer Ebene an.

Gilt für:

Siehe auch