2009-04-22 9 views
1

Ich las this Artikel, in dem sie diesen Code haben:Deserialisierung erfordert Gießen?

// 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); 

Ist die letzte Zeile ein gegossenes Aussage? Wenn ja, beeinträchtigt das nicht die Serialisierungsleistung?

Antwort

6

Ja, die letzte Zeile ist eine Cast-Anweisung. Casting ist mit Kosten verbunden, ist aber im Vergleich zu den Kosten der Serialisierung unbedeutend. Ich bezweifle, dass es sogar auf einem Profiler auftauchen würde.

Denken Sie daran, was Serialisierung beinhaltet.

  • Verarbeitung eines Bytedatenstream
  • Erstellen von Typen auf Basis von Metadaten-Informationen
  • Konvertierung zwischen Byte-Arrays und Datentypen

Jede dieser Operationen sind deutlich teurer als ein Guss Betrieb.

EDIT Warum es Gießen überhaupt benötigt.

Es gibt ein paar Gründe hier. Der erste besteht darin, dass die Deserialisierungs-APIs keine Möglichkeit haben, den Typ des Byte-Streams zu kennen, bevor dieser inspiziert wird. Die einzige Option, die die API in Bezug auf einen Rückgabetyp in Metadaten hat, ist Objekt.

Zweitens muss Deserialisierung buchstäblich jeden Typ unterstützen, der serialisierbar ist. Um zu funktionieren, muss es einen Rückgabetyp für die Methode auswählen, der für alle Typen gilt, die serialisiert werden können. Der einzige verfügbare Typ ist das Objekt.

+0

Danke Jared. Der Grund, warum ich mich gefragt habe, ist, weil ich die Serialisierung für mein gespeichertes Dateisystem in meiner App verwenden möchte, aber die Dateien könnten Millionen von Objekten enthalten. Weißt du, warum es eine Besetzung erfordert? dh. Warum ist es nicht sicher? –

+2

@Joan erfordert eine Umwandlung, da die Deserialisierungsengine den Typ nicht kennt, bevor die zugrunde liegenden Daten gelesen werden. Außerdem gab es die API schon vor Generics, weshalb sie gezwungen wurde, das Objekt als Typ zurückzugeben. – JaredPar

+0

Danke Jared, gut zu wissen. Ist es also möglich, einen Serializer zu haben, der den Typ ohne Casting zurückgibt? –

3

Casts sind im Vergleich zu den Deserialisierungskosten sehr günstig. Der Prozess der Deserialisierung ist ziemlich komplex - eine einzelne (Arbeits-) Besetzung braucht kaum Zeit.

Natürlich, wenn Sie in schnelle, tragbare, kompakte Serialisierung mit einer guten Versionsgeschichte interessiert sind, sollten Sie auf Protocol Buffers suchen:

(Es gibt andere Serialisierung fr ameworks, wie Thrift.)

+0

Danke Jon. Ich bin mir nicht sicher, wie die Serialisierung unter der Haube funktioniert. Weißt du, warum es eine Besetzung erfordert? dh. Warum ist es nicht sicher? –

+1

Schauen Sie sich den Rückgabetyp aus der API an, der vor Generics erstellt wurde. Es gibt wirklich nicht viel, was du tun könntest, um das zu vermeiden. –

+0

Danke Jon. Ist es also möglich, einen Serializer zu haben, der den Typ ohne Casting zurückgibt? Nur aus Neugier :) –

0

Deserialize gibt einen Typ Object zurück, so dass das Casting es in die richtige Klasse bringt.

Ob dies Auswirkungen auf die Deserialisierung hat oder nicht, möchten Sie, dass es Bestandteil von ShoppingList ist.

1

Die Deserialize() -Methode gibt ein Objekt zurück und muss in den richtigen Typ "umgewandelt" werden.

Casting sagt dem Compiler hauptsächlich, dass Sie wissen, was der Objekttyp ist, da der Compiler seinen Typ nicht ableiten kann.Die Laufzeit generiert weiterhin eine InvalidCast-Ausnahme, wenn der Typ nicht dem entspricht, den Sie angegeben haben (oder einem Untertyp des angegebenen Typs).

Die tatsächlichen Kosten für das Gießen sind minimal.

+0

Ich stimme Ihrer Aussage über den Schluss des Typs nicht zu. Es versucht nicht einmal, den Typ abzuleiten, da die Serialisierung lange vor Generics in .NET stattfand. – Samuel

+0

Ich höre dich. Ich denke, ich spreche sehr allgemein.Wir werfen ein, weil type at runtine vom Compiler (zur Kompilierzeit) nicht bekannt ist. Vielleicht keine korrekte Verwendung des Begriffs "infer". – andleer

0

Wenn Sie die letzte Zeile Code ändern

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

zu

newList = s.Deserialize(r); 

Der Compiler wird in einem insg zurück. Ich habe dies gerade mit dem .NET Reflektor von Red Gate bestätigt. Unabhängig von den Kosten für das Casting müssen Sie dies tun, wenn Sie das typisierte Objekt verwenden möchten.