Exception.Data 屬性

定義

取得一組鍵值對,提供關於例外的額外使用者定義資訊。

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

屬性值

一個實作介面 IDictionary 的物件,包含一組使用者定義的鍵值對。 預設是空集合。

範例

以下範例示範如何使用該 Data 屬性新增與檢索資訊。

// 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.

備註

使用 System.Collections.IDictionary 屬性返回的 Data 物件來儲存和檢索與例外狀況相關的補充資訊。 資訊以任意數量的使用者定義鍵值對呈現。 每個索引鍵/值組的索引鍵元件通常是識別字串,而配對的值元件可以是任何類型的物件。

金鑰/值組安全性

儲存在由 Data 屬性傳回的集合中的鍵值組並不安全。 如果您的應用程式呼叫巢狀的例程系列,而且每個例程都包含例外狀況處理程式,則產生的呼叫堆疊會包含這些例外狀況處理程式的階層。 如果較低層級的例程擲回例外狀況,則呼叫堆棧階層中的任何上層例外狀況處理程式都可以讀取和/或修改任何其他例外狀況處理程式儲存在集合中的索引鍵/值組。 這表示您必須保證鍵值對中的資訊不是機密的,而且即使鍵值對中的資訊損毀,您的應用程式也能正常運作。

主要衝突

當不同的例外狀況處理程式指定相同的索引鍵來存取索引鍵/值組時,就會發生索引鍵衝突。 開發應用程式時請小心,因為索引鍵衝突的後果是較低層級的例外狀況處理程式可能會不小心與較高層級的例外狀況處理程序通訊,而且此通訊可能會導致細微的程序錯誤。 不過,如果您謹慎,您可以使用密鑰衝突來增強應用程式。

避免金鑰衝突

採用命名慣例來生成鍵值對的唯一鍵,以避免鍵衝突。 例如,命名慣例可能會產生索引鍵,其中包含以句點分隔的應用程式名稱、提供配對補充資訊的方法,以及唯一標識符。

假設兩個名為 Products 和 Suppliers 的應用程式,每個應用程式都有一個名為 Sales 的方法。 Products 應用程式中的 Sales 方法會提供產品的標識碼(庫存單位或 SKU)。 供應商應用程式中的 Sales 方法會提供供應商的識別碼或 SID。 因此,此範例的命名慣例會產生密鑰 “Products.Sales.SKU” 和 “Suppliers.Sales.SID”。

利用關鍵衝突

利用一或多個特殊、預先安排的密鑰來控制處理,以利用密鑰衝突。 假設在一個案例中,呼叫堆疊階層中的最高層級例外狀況處理程式會攔截較低層級例外狀況處理程序擲回的所有例外狀況。 如果具有特殊索引鍵的索引鍵/值組存在,則高階例外狀況處理程式會以某些非標準方式格式化物件中的 IDictionary 剩餘索引鍵/值組;否則,其餘索引鍵/值組會以某種一般方式格式化。

現在假設在另一個案例中,呼叫堆疊階層的每個層級的例外狀況處理程式會攔截下一個較低層級例外狀況處理程序擲回的例外狀況。 此外,每個例外狀況處理程式都知道 屬性所 Data 傳回的集合包含一組索引鍵/值組,可使用預先排列的索引鍵集來存取。

每個例外狀況處理程式都會使用預先排列的索引鍵集來更新對應索引鍵/值組的值元件,以及該例外狀況處理程式唯一的資訊。 更新程式完成之後,例外狀況處理程式會將例外狀況擲回至下一個較高層級的例外狀況處理程式。 最後,最高層級的例外狀況處理程式會存取索引鍵/值組,並顯示來自所有較低層級例外狀況處理程式的合併更新資訊。

適用於

另請參閱