基本的なシリアル化Basic serialization

警告

バイナリ シリアル化は危険です。Binary serialization can be dangerous. 信頼できないソースからのデータの逆シリアル化、および管理下にないシステムへのラウンドトリップのシリアル化をしてはいけません。Never deserialize data from an untrusted source and never round-trip serialized data to systems not under your control.

クラスをシリアル化できるようにするための最も簡単な方法は、次に示すように SerializableAttribute でマークすることです。The easiest way to make a class serializable is to mark it with the SerializableAttribute as follows.

[Serializable]  
public class MyObject {  
  public int n1 = 0;  
  public int n2 = 0;  
  public String str = null;  
}  

このクラスのインスタンスをファイルにシリアル化する方法を、次のコード例に示します。The following code example shows how an instance of this class can be serialized to a file.

MyObject obj = new MyObject();  
obj.n1 = 1;  
obj.n2 = 24;  
obj.str = "Some String";  
IFormatter formatter = new BinaryFormatter();  
Stream stream = new FileStream("MyFile.bin", FileMode.Create, FileAccess.Write, FileShare.None);  
formatter.Serialize(stream, obj);  
stream.Close();  

この例では、バイナリ フォーマッタを使用してシリアル化します。This example uses a binary formatter to do the serialization. 必要な作業は、使用するストリームのインスタンスとフォーマッタを作成し、フォーマッタで Serialize メソッドを呼び出すことだけです。All you need to do is create an instance of the stream and the formatter you intend to use, and then call the Serialize method on the formatter. ストリームとシリアル化するオブジェクトを、この呼び出しのパラメーターとして指定します。The stream and the object to serialize are provided as parameters to this call. この例では明示的に示されていませんが、クラスのすべてのメンバー変数は、変数がプライベートとして指定されている場合でもシリアル化されます。Although it is not explicitly demonstrated in this example, all member variables of a class will be serialized—even variables marked as private. この点で、バイナリ シリアル化は、パブリック フィールドのみをシリアル化する XmlSerializer クラスとは異なります。In this aspect, binary serialization differs from the XmlSerializer class, which only serializes public fields. バイナリ シリアル化からメンバー変数を除外する方法については、「選択的シリアル化」を参照してください。For information on excluding member variables from binary serialization, see Selective Serialization.

オブジェクトを元の状態に復元することも、同じように簡単にできます。Restoring the object back to its former state is just as easy. 最初に、読み取るストリームと Formatter を作成してから、フォーマッタに対してオブジェクトの逆シリアル化を指示します。First, create a stream for reading and a Formatter, and then instruct the formatter to deserialize the object. この処理を行うコード例を次に示します。The code example below shows how this is done.

IFormatter formatter = new BinaryFormatter();  
Stream stream = new FileStream("MyFile.bin", FileMode.Open, FileAccess.Read, FileShare.Read);  
MyObject obj = (MyObject) formatter.Deserialize(stream);  
stream.Close();  
  
// Here's the proof.  
Console.WriteLine("n1: {0}", obj.n1);  
Console.WriteLine("n2: {0}", obj.n2);  
Console.WriteLine("str: {0}", obj.str);  

前の例で使用している BinaryFormatter は非常に効率的であり、コンパクトなバイト ストリームを生成します。The BinaryFormatter used above is very efficient and produces a compact byte stream. このフォーマッタでシリアル化されたすべてのオブジェクトは、同じフォーマッタで逆シリアル化することもできるため、これは .NET Framework で逆シリアル化されるオブジェクトをシリアル化するための最適なツールです。All objects serialized with this formatter can also be deserialized with it, which makes it an ideal tool for serializing objects that will be deserialized on the .NET Framework. オブジェクトの逆シリアル化中は、コンストラクターが呼び出されないことに注意してください。It is important to note that constructors are not called when an object is deserialized. パフォーマンス上の理由から、逆シリアル化に対してこの制約が設けられています。This constraint is placed on deserialization for performance reasons. ただし、この制約はランタイムがオブジェクト作成者と結ぶ通常の協定の一部に違反するため、開発者は、オブジェクトをシリアル化可能としてマークするときに生じる影響を理解する必要があります。However, this violates some of the usual contracts the runtime makes with the object writer, and developers should ensure that they understand the ramifications when marking an object as serializable.

移植性が必要な場合には、代わりに SoapFormatter を使用します。If portability is a requirement, use the SoapFormatter instead. その場合は、コード内の BinaryFormatterSoapFormatter に置き換え、前のコードと同様に Serialize および Deserialize を呼び出します。Simply replace the BinaryFormatter in the code above with SoapFormatter, and call Serialize and Deserialize as before. 前の例では、このフォーマッタの出力は、次のようになります。This formatter produces the following output for the example used above.

<SOAP-ENV:Envelope  
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"   
  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"  
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"  
  SOAP-ENV:encodingStyle=  
  "http://schemas.microsoft.com/soap/encoding/clr/1.0"  
  "http://schemas.xmlsoap.org/soap/encoding/"  
  xmlns:a1="http://schemas.microsoft.com/clr/assem/ToFile">  
  
  <SOAP-ENV:Body>  
    <a1:MyObject id="ref-1">  
      <n1>1</n1>  
      <n2>24</n2>  
      <str id="ref-3">Some String</str>  
    </a1:MyObject>  
  </SOAP-ENV:Body>  
</SOAP-ENV:Envelope>  

Serializable 属性は継承できないことに注意してください。It's important to note that the Serializable attribute cannot be inherited. MyObject から新しいクラスを派生させる場合は、その新しいクラスもこの属性でマークする必要があります。マークしないと、このクラスをシリアル化できません。If you derive a new class from MyObject, the new class must be marked with the attribute as well, or it cannot be serialized. たとえば、次に示すクラスのインスタンスをシリアル化しようとすると、MyStuff 型がシリアル化可能としてマークされていないことを通知する SerializationException が表示されます。For example, when you attempt to serialize an instance of the class below, you'll get a SerializationException informing you that the MyStuff type is not marked as serializable.

public class MyStuff : MyObject   
{  
  public int n3;  
}  

Serializable 属性を使用すると便利ですが、このような制限事項があります。Using the Serializable attribute is convenient, but it has limitations as previously demonstrated. シリアル化するクラスをマークするタイミングについては、「シリアル化のガイドライン」を参照してください。Refer to the Serialization Guidelines for information about when you should mark a class for serialization. クラスをコンパイルした後でシリアル化を追加することはできません。Serialization cannot be added to a class after it has been compiled.

関連項目See also