2009-04-22 12 views
1

私は、彼らがこのコードを持っているthis記事、読んでいた:逆シリアル化にはキャストが必要ですか?

// Serialization 
XmlSerializer s = new XmlSerializer(typeof(ShoppingList)); 
TextWriter w = new StreamWriter(@"c:\list.xml"); 
s.Serialize(w, myList); 
w.Close(); 

// Deserialization 
ShoppingList newList; 
TextReader r = new StreamReader("list.xml"); 
newList = (ShoppingList)s.Deserialize(r); 

キャスト文の最後の行ですが?もしそうなら、それは直列化のパフォーマンスを低下させませんか?

答えて

6

はい最後の行はキャストステートメントです。キャスティングにはコストがかかりますが、シリアライゼーションのコストと比較するとそれほど重要ではありません。私はそれがプロファイラに現れることさえ疑う。

シリアライゼーションの内容を考えてください。バイト配列とデータ型

  • メタデータ情報に基づいてタイプを作成するバイトストリーム
  • を処理
  • 変換これらの操作のいずれも著しく高価シングルキャスト操作よりもあります。

    EDITなぜ、キャストする必要があるのか​​。

    ここにはいくつかの理由があります。 1つ目は、逆シリアル化APIはバイトストリームのタイプを調べる前にそれが何であるかを知る方法がないことです。したがって、メタデータの戻り値の型に関してAPIが持つ唯一の選択肢は、Objectです。

    第2に、直列化解除は文字通り直列化可能な任意の型をサポートする必要があります。これを機能させるには、直列化できるすべての型に適用可能なメソッドの戻り値の型を選択する必要があります。それを満たす唯一のタイプはオブジェクトです。

+0

ありがとうございます。私が思った理由は、私のアプリケーションで私の保存ファイルシステムのシリアル化を使用したいが、ファイルに何百万ものオブジェクトが含まれている可能性があるからです。なぜキャストが必要なのか分かりませんか?すなわち、なぜそれはタイプセーフではないのですか? –

+2

@ Joanデシリアライゼーションエンジンは、基になるデータを読み取る前にタイプを認識しないため、キャストが必要です。また、APIはジェネリックより前から存在していたので、typeとしてオブジェクトを返すように強制されました。 – JaredPar

+0

Jaredさん、ありがとうございました。したがって、キャストせずに型を返すシリアライザを使用することは可能ですか? –

3

キャストは、デシリアライズコスト自体と比較して非常に安いです。デシリアライゼーションのプロセスはかなり複雑です。単一の(動作する)キャストはほとんど時間がかかりません。

もちろん

あなたが良いバージョニングの話で、高速、ポータブル、コンパクトな直列化に興味があるなら、あなたはプロトコルバッファを見てする必要があります。

(他のシリアライズfrがあります。また、Thriftのようなものもあります。)

+0

ありがとうございました。私は実際にどのようにシリアル化がボンネットの下で動作するかはわかりません。なぜキャストが必要なのか分かりませんか?すなわち、なぜそれはタイプセーフではないのですか? –

+1

ジェネリックスの前に作成されたAPIの戻り値の型を調べます。あなたがそれを避けるためにできることはあまりありません。 –

+0

ありがとうございました。したがって、キャストせずに型を返すシリアライザを使用することは可能ですか?好奇心からちょうど:) –

0

Deserializeは、正しいクラスにキャストするためにtypeオブジェクトを返します。

これがデシリアライズに影響を与えるかどうかは、それがShoppingListの一部であることを望みます。

1

Deserialize()メソッドはオブジェクトを返し、正しい型にキャストする必要があります。

キャストは、主に、コンパイラがその型を推論することができないため、オブジェクト型が何であるかをコンパイラに伝えています。タイプが指定したタイプ(または指定されたタイプのサブタイプ)でない場合、ランタイムは引き続きInvalidCast例外を生成します。

キャスティングの実際のコストは最小です。あなたは

newList = s.Deserialize(r); 

にコード

newList = (ShoppingList)s.Deserialize(r); 

の最後の行を変更した場合

+0

私はそのタイプを推論することについてあなたの陳述に同意しません。シリアル化はジェネリックよりもずっと前に.NETで行われていたため、型を推測することさえできません。 – Samuel

+0

私はあなたを聞いています。私は非常に一般的な用語で話していると思います。runtineの型は(コンパイル時に)コンパイラによって未知であるため、キャストします。 「推論」という用語を正しく使用していない可能性があります。 – andleer

0

コンパイラはキャストに戻って追加されます。私はRed Gateの.NET Reflectorでこれを確認しました。したがって、キャストのコストにかかわらず、その型付きオブジェクトを使用する必要がある場合は、それを実行する必要があります。

関連する問題