2009-08-03 7 views
1

Ich habe ein statisches generisches Wörterbuch in einer Klasse. Da das statische Member nicht serialisiert werden kann, habe ich die ISerializable-Schnittstelle und die Methode GetObjectData zur Serialisierung implementiert. Ich habe einen Konstruktor, der auch SerializationInfo und StreamingContext akzeptiert, um den Dictionay zu desertieren. Jetzt, wenn ich serialisieren und deserialisieren will, gibt es immer 1 zurück (ich habe 2 Einträge hinzugefügt). bitte finden Sie die pseduo code-DeSerialization funktioniert nicht, obwohl ich GetObjectData Methode und Konstruktor implementieren

[Serializable] 
public class MyClass : ISerializable 
{ 
    internal static Dictionary<long, string> dict = new Dictionary<long,string>(); 

    public void GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
    info.AddValue("static.dic", MyClass1.dict, typeof(Dictionary<long, string>)); 
    } 

    public MyClass(SerializationInfo info, StreamingContext context) 
    { 
    MyClass.dict= (Dictionary<long, string>)info.GetValue("static.dic", 
     typeof(Dictionary<long, string>)); 

    } 
    public void Add() 
    { 
    dict.Add(21, "11"); 
    } 

    public MyClass() 
    { 
    dict.Add(21, "11"); 
    } 
} 


    public class MyClass 
    {  
     MyClass myClass = new MyClass(); 

     public static void Main() 
     { 
      myClass.Add(); 

      FileStream fileStream = new FileStream("test.binary", FileMode.Create); 

      IFormatter bf = new BinaryFormatter(); 

      bf.Serialize(fileStream, myClass); 

      fileStream.Dispose(); 

      fileStream.Close(); 

      fileStream = new FileStream("test.binary", FileMode.Open); 

      bf = new BinaryFormatter(); 

      myClass = (MyClass1)bf.Deserialize(fileStream); 
    } 
} 
+0

Ihr Code sieht fast vollständig aus, wird aber nicht kompiliert.Machen Sie jedem einen Gefallen und verwandeln Sie es zunächst in ein (kurzes) Arbeitsprogramm und posten Sie es dann. –

Antwort

1

Dies ist grundsätzlich völlig falsch.

Sie versuchen, die Serialisierung/Deserialisierung einer Instanz mit einer Änderung des statischen Status einer Klasse zu verknüpfen.

Dieser Status sollte nicht statisch sein, wenn er mit einer Instanz verknüpft ist.

Wenn Sie diesen Wörterverzeichnisstatus mit mehreren Instanzen teilen möchten, muss er unveränderlich sein (damit die Erstellung von einem die anderen nicht beeinflusst). Eine anständige unveränderliche Karte wird dies einfach machen (Freigabe von so viel geteiltem Zustand wie möglich möglich)

1

Es sollte fast sicher nicht statisch sein!

Aber; Angenommen, es handelt sich um Instanzdaten. Haben Sie versucht, einen OnDeserialization Callback hinzuzufügen, der dict.OnDeserialization aufruft?

Bis Sie das tun, kann es unvollständig sein ...

Ein Beispiel finden Sie here.

4

Veröffentlichen Sie nie "Pseudo-Code", wenn Sie genauso einfach Arbeitscode veröffentlichen können, der das Problem aufweist.

Wie auch immer, nach dem Aufräumen Ihres Codes, es funktioniert wie erwartet, in dem Sinne, dass deserializing das Objekt gibt mir ein Wörterbuch mit 2 Elementen. Ich wette, das Problem hängt mit Ihrem statischen Feld-Diktat zusammen. Sie sollten keine statischen Felder wie diese verwenden.

Können Sie den folgenden Code versuchen und uns sagen, was das Problem ist? Dieser Code funktioniert in dem Sinne, dass Sie ihn in die Datei Program.cs einer Konsole oder Winforms-Anwendung einfügen und debuggen können.

Beachten Sie die folgenden Dinge:

  • entfernte ich die static'ness des dict Feld
  • ich die Schlüssel festgelegt Sie für die beiden Elemente verwendet, die Sie hinzugefügt (beide nicht 21 sein kann)
  • Ich habe eine der MyClass-Klassen umbenannt und feste Referenzen auf MyClass1
  • Ich schrieb den Main-Code leicht um using Block statt Anrufe zu .Close() und .Dispose() zu verwenden.

Hier ist der Code:

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

namespace Test 
{ 
    [Serializable] 
    public class MyClass : ISerializable 
    { 
     internal Dictionary<long, string> dict = new Dictionary<long, string>(); 

     public void GetObjectData(SerializationInfo info, StreamingContext context) 
     { 
      info.AddValue("static.dic", dict, typeof(Dictionary<long, string>)); 
     } 

     public MyClass(SerializationInfo info, StreamingContext context) 
     { 
      dict = (Dictionary<long, string>)info.GetValue("static.dic", 
       typeof(Dictionary<long, string>)); 
     } 

     public void Add() 
     { 
      dict.Add(31, "11"); 
     } 

     public MyClass() 
     { 
      dict.Add(21, "11"); 
     } 
    } 

    public class MyClassTest 
    { 
     public static void Main() 
     { 
      MyClass myClass = new MyClass(); 
      myClass.Add(); 

      using (FileStream fileStream = new FileStream("test.binary", FileMode.Create)) 
      { 
       IFormatter bf = new BinaryFormatter(); 
       bf.Serialize(fileStream, myClass); 
      } 

      using (FileStream fileStream = new FileStream("test.binary", FileMode.Open)) 
      { 
       IFormatter bf = new BinaryFormatter(); 
       myClass = (MyClass)bf.Deserialize(fileStream); 
      } 
     } 
    } 
} 
+0

Thnx für Ihre Antworten. Ich benutze statisches Wörterbuch bcoz mein Dictionary hält 20000 Werte, also möchte ich nicht meine SP wieder anrufen, wenn meine Klasse das nächste Mal initialize wird. Ich möchte auch einen neuen Eintrag im Wörterbuch hinzufügen, wenn Benutzer versuchen, einen neuen Eintrag zu speichern. Ich weiß, statische Objekt serialisieren ist Fehler Design, aber in diesem Fall muss ich dict als statische deklarieren, sonst wäre es eine riesige perofmance Overhead. lass ur Code funktioniert, aber können Sie mir sagen, y Count von dict gibt Null zurück, wenn ym Konstruktor aufgerufen wird. (zur Zeit der deserialize) –

+0

Lassse, gibt es eine Möglichkeit tht ich kann grundlegende und gemischte Serialisierung zusammen, bcoz ich brauche nur Dictionay um Benutzerdefiniert zu implementieren, während andere Mitglieder der Klasse auf eine grundlegende/normale Weise serialisiert werden können. –

0

Sie wollen nicht statische Klasse für diesen Einsatz. Sie möchten einen Singleton verwenden, der bei der ersten Erstellung geladen wird. Möglicherweise möchten Sie auch eine Aktualisierungsmethode dort.

Verwandte Themen