Exception.SerializeObjectState Exception.SerializeObjectState Exception.SerializeObjectState Exception.SerializeObjectState Event

定義

例外がシリアル化され、例外に関するシリアル化されたデータを含む例外状態オブジェクトが作成されたときに発生します。Occurs when an exception is serialized to create an exception state object that contains serialized data about the exception.

protected:
 event EventHandler<System::Runtime::Serialization::SafeSerializationEventArgs ^> ^ SerializeObjectState;
protected event EventHandler<System.Runtime.Serialization.SafeSerializationEventArgs> SerializeObjectState;
member this.SerializeObjectState : EventHandler<System.Runtime.Serialization.SafeSerializationEventArgs> 
Protected Custom Event SerializeObjectState As EventHandler(Of SafeSerializationEventArgs) 

次の例ではBadDivisionExceptionSerializeObjectStateイベントを処理するを定義します。The following example defines a BadDivisionException that handles the SerializeObjectState event. また、状態オブジェクトも含まれます。これは、 BadDivisionExceptionState ISafeSerializationDataインターフェイスを実装するという名前の入れ子になった構造体です。It also contains a state object, which is a nested structure named BadDivisionExceptionState that implements the ISafeSerializationData interface.

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

public class Example
{
   public static void Main()
   {
      bool serialized = false;
      var formatter = new BinaryFormatter();
      Double[] values = { 3, 2, 1 };
      Double divisor = 0;
      foreach (var value in values) {
         try {
            BadDivisionException ex = null;
            if (divisor == 0) { 
               if (! serialized) {
                  // Instantiate the exception object.
                  ex = new BadDivisionException(0);
                  // Serialize the exception object.
                  var fs = new FileStream("BadDivision1.dat", 
                                           FileMode.Create);
                  formatter.Serialize(fs, ex);
                  fs.Close();
                  Console.WriteLine("Serialized the exception...");
               }
               else {
                  // Deserialize the exception.
                  var fs = new FileStream("BadDivision1.dat",
                                           FileMode.Open);
                  ex = (BadDivisionException) formatter.Deserialize(fs);
                  // Reserialize the exception.
                  fs.Position = 0;
                  formatter.Serialize(fs, ex);
                  fs.Close();
                  Console.WriteLine("Reserialized the exception...");                                            
               }   
              throw ex; 
            } 
            Console.WriteLine("{0} / {1} = {1}", value, divisor, value/divisor);
         }   
         catch (BadDivisionException e) {
            Console.WriteLine("Bad divisor from a {0} exception: {1}",
                              serialized ? "deserialized" : "new", e.Divisor);             
            serialized = true;
         }   
      }
   }
}

[Serializable] public class BadDivisionException : Exception
{
   // Maintain an internal BadDivisionException state object.
   [NonSerialized] private BadDivisionExceptionState state = new BadDivisionExceptionState();

   public BadDivisionException(Double divisor)
   {
      state.Divisor = divisor;
      HandleSerialization();      
   }
   
   private void HandleSerialization()
   {
      SerializeObjectState += delegate(object exception, SafeSerializationEventArgs eventArgs) 
                                      { 
                                          eventArgs.AddSerializedState(state);
                                      };
   }
   
   public Double Divisor
   { get { return state.Divisor; } }

   [Serializable] private struct BadDivisionExceptionState : ISafeSerializationData 
   {
      private Double badDivisor;
      
      public Double Divisor
      { get { return badDivisor; } 
        set { badDivisor = value; } }

      void ISafeSerializationData.CompleteDeserialization(object deserialized)
      { 
         var ex = deserialized as BadDivisionException;
         ex.HandleSerialization();
         ex.state = this; 
      }
   }
}
// The example displays the following output:
//       Serialized the exception...
//       Bad divisor from a new exception: 0
//       Reserialized the exception...
//       Bad divisor from a deserialized exception: 0
//       Reserialized the exception...
//       Bad divisor from a deserialized exception: 0
Imports System.IO
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Formatters.Binary
           
Module Example
   Public Sub Main()
      Dim serialized As Boolean = False
      Dim formatter As New BinaryFormatter()
      Dim values() As Double = { 3, 2, 1 }
      Dim divisor As Double = 0
      For Each value In values
         Try
            Dim ex As BadDivisionException = Nothing
            If divisor = 0 Then 
               If Not serialized Then
                  ' Instantiate the exception object.
                  ex = New BadDivisionException(0)
                  ' Serialize the exception object.
                  Dim fs As New FileStream("BadDivision1.dat", 
                                           FileMode.Create)
                  formatter.Serialize(fs, ex)
                  fs.Close()
                  Console.WriteLine("Serialized the exception...")
               Else
                  ' Deserialize the exception.
                  Dim fs As New FileStream("BadDivision1.dat",
                                           FileMode.Open)
                  ex = CType(formatter.Deserialize(fs), BadDivisionException)
                  ' Reserialize the exception.
                  fs.Position = 0
                  formatter.Serialize(fs, ex)
                  fs.Close()
                  Console.WriteLine("Reserialized the exception...")                                            
               End If   
              Throw ex 
            End If 
            Console.WriteLine("{0} / {1} = {1}", value, divisor, value/divisor)
         Catch e As BadDivisionException
            Console.WriteLine("Bad divisor from a {0} exception: {1}",
                              If(serialized, "deserialized", "new"), e.Divisor)             
            serialized = True
         End Try   
      Next
   End Sub
End Module

<Serializable> Public Class BadDivisionException : Inherits Exception
   ' Maintain an internal BadDivisionException state object.
   <NonSerialized> Private state As New BadDivisionExceptionState()

   Public Sub New(divisor As Double)
      state.Divisor = divisor
      HandleSerialization()      
   End Sub
   
   Private Sub HandleSerialization()
      AddHandler SerializeObjectState, 
                 Sub(exception As Object, eventArgs As SafeSerializationEventArgs)
                    eventArgs.AddSerializedState(state)
                 End Sub
   End Sub
   
   Public ReadOnly Property Divisor As Double
      Get
         Return state.Divisor
      End Get      
   End Property

   <Serializable> Private Structure BadDivisionExceptionState 
                                    Implements ISafeSerializationData
      private badDivisor As Double
      
      Public Property Divisor As Double
         Get
            Return badDivisor
         End Get
         Set
            badDivisor = value
         End Set
      End Property 

      Sub CompleteDeserialization(deserialized As Object) _
            Implements ISafeSerializationData.CompleteDeserialization
         Dim ex As BadDivisionException = TryCast(deserialized, BadDivisionException)
         ex.HandleSerialization()
         ex.state = Me 
      End Sub
   End Structure
End Class
' The example displays the following output:
'       Serialized the exception...
'       Bad divisor from a new exception: 0
'       Reserialized the exception...
'       Bad divisor from a deserialized exception: 0
'       Reserialized the exception...
'       Bad divisor from a deserialized exception: 0

このBadDivisionException例外は、0による浮動小数点除算が発生した場合にスローされます。The BadDivisionException exception is thrown when a floating-point division by zero occurs. 0による最初の除算では、 BadDivisionExceptionオブジェクトをインスタンス化してシリアル化し、例外をスローします。During the first division by zero, the example instantiates a BadDivisionException object, serializes it, and throws the exception. 後続の除算が0の場合、この例では、以前にシリアル化されたオブジェクトを逆シリアル化し、そのオブジェクトを再シリアル化して、例外をスローします。When subsequent divisions by zero occur, the example deserializes the previously serialized object, reserializes it, and throws the exception. オブジェクトのシリアル化、逆シリアル化、再シリアル化、および逆シリアル化をSerializeObjectState提供するために、 BadDivisionExceptionこの例では、 ISafeSerializationData.CompleteDeserializationクラスコンストラクターと実装の両方にイベントハンドラーを追加します。To provide for object serialization, deserialization, reserialization, and deserialization, the example adds the SerializeObjectState event handler both in the BadDivisionException class constructor and in the ISafeSerializationData.CompleteDeserialization implementation.

注釈

例外状態オブジェクトは、インターフェイスISafeSerializationDataを実装します。The exception state object implements the ISafeSerializationData interface.

SerializeObjectStateイベントがサブスクライブされると、例外が逆シリアル化され、空の例外として作成されます。When the SerializeObjectState event is subscribed to, the exception is deserialized and created as an empty exception. 例外のコンストラクターは実行されず、例外の状態も逆シリアル化されます。The exception's constructor is not run, and the exception state is also deserialized. 次に、例外状態オブジェクトのコールバックメソッドに通知し、逆シリアル化されたデータを空の例外にプッシュできるようにします。CompleteDeserializationThe CompleteDeserialization callback method of the exception state object is then notified so that it can push deserialized data into the empty exception.

イベントSerializeObjectStateを使用すると、透過的な例外の種類で例外データをシリアル化および逆シリアル化できます。The SerializeObjectState event enables transparent exception types to serialize and deserialize exception data. 透過的なコードは、操作中のアクセス許可セットの境界内でコマンドを実行できますが、実行、呼び出し、派生、またはクリティカルコードを含むことはできません。Transparent code can execute commands within the bounds of the permission set it is operating within, but cannot execute, call, derive from, or contain critical code.

イベントがサブスクライブされていない場合、シリアル化は通常Exceptionどおりコンストラクターを使用して発生します。 SerializeObjectStateIf the SerializeObjectState event is not subscribed to, deserialization occurs as usual using the Exception constructor.

通常、 SerializeObjectStateイベントのハンドラーは、例外のコンストラクターに追加され、シリアル化を提供します。Typically, a handler for the SerializeObjectState event is added in the exception's constructor to provide for its serialization. ただし、イベントハンドラーのSerializeObjectState実行時にコンストラクターは実行されないため、逆シリアル化された例外をシリアル化すると、例外を逆シリアル化しようとするとSerializationException例外がスローされる可能性があります。But because the constructor is not executed when the SerializeObjectState event handler executes, serializing a deserialized exception can throw a SerializationException exception when you try to deserialize the exception. これを回避するには、 SerializeObjectState ISafeSerializationData.CompleteDeserializationメソッドでイベントのハンドラーを追加する必要もあります。To avoid this, you should also add the handler for the SerializeObjectState event in the ISafeSerializationData.CompleteDeserialization method. 例については、「例」を参照してください。See the Examples section for an illustration.

注意 (継承者)

このイベントがサブスクライブされて使用されている場合は、継承階層内の後続のすべての派生型が同じシリアル化機構を実装する必要があります。If this event is subscribed to and used, all derived types that follow in the inheritance hierarchy must implement the same serialization mechanism.

適用対象