Допомагаємо ЗСУ!

C# Serialization

🟠 20:37 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
Статус: Offline
Реєстрація: 27.11.2008
Повідом.: 87
  • 🟠 20:37 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
  • #1
Проблемма с сериализацией массива. Вот следующий стандартный код:
Код:
SaveFileDialog save = new SaveFileDialog();

            save.Filter = "File Clients(*.cli)|*.cli";
            save.InitialDirectory = ".\\Save";

            if (save.ShowDialog() == DialogResult.OK)
            {
                BinaryFormatter binFormat = new BinaryFormatter();

                using(Stream fStream = new FileStream(save.FileName,
 FileMode.Create, FileAccess.Write, FileShare.None)) 
                { 
                    binFormat.Serialize(fStream, clients); 
                } 
            }

где clients - поле обьявленное в классе MainWindow
Код:
private List<Client> clients = new List<Client>();

выдает ошибку во время выполнения (компилятор нечего неговорит):

System.Runtime.Serialization.SerializationException: Type '....MainWindow' in Assembly '..., Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.


Но я ведь не пытаюсь сериализовать MainWindow, почему он пытаеться сериализовать MainWindow?
 
  • 🟠 20:37 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
  • #2
во первых непонятно что за класс Client? От кого он наследуется и какие элементы содержит?

во вторых, если ты будешь использовать BinaryFormatter для сохранения данных, то в один прекрасный день столкнешься с тем что тебе захочется внести изменения в код и когда ты перебилдишь проект, то обнаружишь что ты уже не сможешь прочитать все сохраненные данные записанные предыдущей версией ;)
 
  • 🟠 20:37 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
  • #3
во первых непонятно что за класс Client? От кого он наследуется и какие элементы содержит?

во вторых, если ты будешь использовать BinaryFormatter для сохранения данных, то в один прекрасный день столкнешься с тем что тебе захочется внести изменения в код и когда ты перебилдишь проект, то обнаружишь что ты уже не сможешь прочитать все сохраненные данные записанные предыдущей версией ;)

Код:
    [Serializable]
    class Client
    {
        // ======================== C O N S T R U C T O R S 

        
        // constuctos takes name and structure of receive telegramm
        public Client(string name, List<ReciveData> telegram, Boiler boiler)
        

        // ================================ F I L D S =======================================

        // thread whose work witch run client
        [NonSerialized]
        private Thread thread;

        // connection stream
        [NonSerialized]
        private NetworkStream _readStream;

        // structure of telegram
        private List<ReciveData> structTelegram;

        // parameters of boiler
        private Boiler _boiler;

        // ============================= B E H A V I O R ====================================

        // property to set or get read stream
        public NetworkStream ReadStream
        {
            set ...
            get ...
        }

        // set or get client name 
        public string Name { set; get; }
        
        // get status of client
        public bool Active
        {
            get
            ...
        }
        
        // get structure of telegramm
        public List<ReciveData> Struct
        {
            get { return structTelegram; }
        }

        // get client thread
        public Thread ClientThread
        {
            get { return thread; }
        }

        // ============================== M E T H O D S =====================================

        public void runClient()
        {
            ...
        }// end runClient

        private bool writeDataToFile()
        {
            ...
        }//end function writeDataToFile

        public override string ToString()
        {
            return this.Name;
        }

        // =============================== E V E N T S =====================================

        public event EventHandler setDataEvent;
        public event EventHandler<ReciveTelegramEventArgs> getDataEvent;
    }//end class Client

A что вы посоветуете во вторых XmlSerealization ?
 
  • 🟠 20:37 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
  • #4

Я не думаю что сериализовать Thread это хорошая идея... :D Также как и NetworkStream и контролы с формами ;)
В вашем классе есть экземпляр EventHandler, очевидно предположить что вы добавили обработчик в виде метода, реализованного как я полагаю в классе формы. Отсюда и ошибка - сериализатору необходимо сохранить информацию MethodInfo и Target объекта (в вашем случае это ссылка на объект формы и метод принимающий эти события), сериализатор такое делать не умеет.

A что вы посоветуете во вторых XmlSerealization ?

у XmlSerializer имеются свои тараканы. Самый надежный и простой способ - ручная сериализация:

Код:
public interface IGoodSerializable
{
   void SerializeTo(XmlNode node, string tagName);
   void DeserializeFrom(XmlNode node);
}

public class MyEntity : IGoodSerializable
{
   private int m_myValue;


   #region IGoodSerializable

   private const string csXmlAttrMyValue = "myValue";

   public virtual void SerializeTo(XmlNode node, string tagName)
   {
      XmlElement xe = node.OwnerDocument.CreateElement(tagName);
      xel.SetAttribute(csXmlAttrMyValue, m_myValue.ToString());
      node.AppendChild(xel);
   }

   public virtual void DeserializeFrom(XmlNode node)
   {
      if(node.Attributes[csXmlAttrMyValue]!=null)
         m_myValue = int.Parse(node.Attributes[csXmlAttrMyValue].InnerText);
   }
   #endregion //IGoodSerializable

}

Загрузка и сохранение коллекции энтитей:
Код:
// Save MyEntity collection to file:
XmlDocument xml = new XmlDocument();
XmlNode root = xml.AppendChild(xml.CreateElement("MyXmlFile"));
foreach(MyEntity me in entityCollection)
   me.SerializeTo(root, "MyEntity");
xml.Save("myfile.xml");

// Load MyEntity collection from file:
XmlDocument xml = new XmlDocument();
xml.Load("myfile.xml");
List<MyEntity> list = new List<MyEntity>();
foreach(XmlNode node in xml["MyXmlFile"].SelectNodes("MyEntity"))
{   
   MyEntity me = new MyEntity();
   me.DeserializeFrom(node);
   list.Add(me);
}
 
Останнє редагування:
  • 🟠 20:37 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
  • #5
Я не думаю что сериализовать Thread это хорошая идея... :D Также как и NetworkStream и контролы с формами ;)

Thread и NetvorkString у меня помечены как [NonSerialized], т.е. в сериализации они не учавствуют!

В вашем классе есть экземпляр EventHandler, очевидно предположить что вы добавили обработчик в виде метода, реализованного как я полагаю в классе формы. Отсюда и ошибка - сериализатору необходимо сохранить информацию MethodInfo и Target объекта (в вашем случае это ссылка на объект формы и метод принимающий эти события), сериализатор такое делать не умеет.

А вот за это спасибо действительно неподумал.

у XmlSerializer имеются свои тараканы. Самый надежный и простой способ - ручная сериализация:

Об этом подумаю спасибо.
 
  • 🟠 20:37 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
  • #6
А вот за это спасибо действительно неподумал.

еще раз повторяю, если вы будете использовать BinaryFormatter, то вы не сможете прочитать то что было записано другой версией вашей программы ;) Этот форматтер не предназначен для хранения данных, он ориентирован на передачу данных, т.к. сохраняет версию сборки которой сериализован объект, поэтому попытка чтения из версии сборки отличной от той которая производила запись приведет к ошибке. И восстановить записанные данные будет очень сложно и проблемно, вам это будет не под силу, т.к. потребует доскональный знаний внутренностей дотнет фреймворка и ручного побайтового разбора содержимого файлов.

В крайнем случае для сохранения лучше XmlSerializer использовать, но никак не BinaryFormatter. Но ручная сериализация будет быстрее и надежнее
 
  • 🟠 20:37 Загроза ударних БпЛА Загроза БпЛА типу «Шахед»#м_Харків_та_Харківська_територіальна_громада
  • #7
еще раз повторяю, если вы будете использовать BinaryFormatter, то вы не сможете прочитать то что было записано другой версией вашей программы ;) Этот форматтер не предназначен для хранения данных, он ориентирован на передачу данных, т.к. сохраняет версию сборки которой сериализован объект, поэтому попытка чтения из версии сборки отличной от той которая производила запись приведет к ошибке. И восстановить записанные данные будет очень сложно и проблемно, вам это будет не под силу, т.к. потребует доскональный знаний внутренностей дотнет фреймворка и ручного побайтового разбора содержимого файлов.

В крайнем случае для сохранения лучше XmlSerializer использовать, но никак не BinaryFormatter. Но ручная сериализация будет быстрее и надежнее
Однако,следует отметить,данное творение искуства самообладания кодом ,писянным вне закона расположения намагниченной последовательности нулей на дверях програмируемого сектора,дает нам полные основания утверждать,что в недрах Земли жизнь есть в виде сериализованных колбасных отходов ,доступ к которым возможен через побайтовый разбор шнека.
 
Назад
Зверху Знизу