Сериализация: как десериализовать в C#

#c# #serialization #deserialization

#c# #сериализация #десериализация

Вопрос:

Как я могу десериализовать строку на основе того, что я сделал в этом методе? По сути, то, что у меня здесь есть, это передать строку через сеть с помощью сериализации и десериализовать строку, чтобы передать сообщение. Но как только мне удалось получить сообщение, я понятия не имею, правильно ли то, что я делаю. Вот код:

 string ConvertToString(FrogGame np, Frog1 pm, Frog2 pm2) //Serialization. the three parameters are the classes. 
        {
            XmlSerializer sendSerializer = new XmlSerializer(typeof(FrogGame),new Type[]{typeof(Frog1),typeof(Frog2)});
            StreamWriter myWriter = new StreamWriter(@"pad1.xml");
            sendSerializer.Serialize(myWriter, np);
            sendSerializer.Serialize(myWriter, pm);
            sendSerializer.Serialize(myWriter, pm2);
            return myWriter.ToString();
        } //Overall, I serialize it into string
  

Как только я передаю строку по сети, я хочу десериализовать ее, чтобы передать сообщение классам. Как мне продолжить здесь и далее? Как я могу редактировать? Код:

 void StringReceived(string str) //so str is myWriter.ToString()
        {
            XmlSerializer revSerializer = new XmlSerializer(typeof(FrogGame), new Type[] { typeof(Frog1), typeof(Frog2) });
            FileStream myFileStream = new FileStream(@"pad1.xml", FileMode.Open);
            FrogGame b = (FrogGame)revSerializer.Deserialize(myFileStream);

            if (b is Frog1) 
            {
                if (Network.IsServer())
                {
                    pm = (Frog1)b;
                    pm.Position.Y = b.pm.Position.Y;
                    pm.Position.X = b.pm.Position.X;
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine("BAD Message: "   msg);
                }
            }

            else if (b is Frog2)
            {
                if (Network.IsClient())
                {
                    pm2 = (PaddleMessage2)b;
                    pm2.Position.Y = b.pm2.Position.Y;
                    pm2.Position.X = b.pm2.Position.X;
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine("BAD Message: "   msg);
                }
            }

        }
  

Комментарии:

1. Вы должны использовать JSON, потому что XML просто создает ненужные накладные расходы.

2. Я слышал, что JSON лучше, но сериализация XML проще для начала. Так что просто попробуйте сериализацию XML, прежде чем двигаться дальше. Итак, вы знаете, как ввести строку в xmlserialiser для ее десериализации?

3. Почему вы сериализуете файл, когда хотите отправить строку по сети? StringWriter Вместо этого используйте a . Или просто используйте сетевой поток. Кстати, возврат myWriter.ToString() , вероятно, не то, что вы хотите. У вас возникли проблемы с вашим кодом? Вы проверили сообщения?

4. @NicoSchertler Хорошо. Так можно ли вместо этого отправить весь MyWriter?

5. Нет, это не так. Вы должны отправить строковый результат сериализатора. Вы можете использовать a StringWriter для сериализации в строку вместо файла. Тогда ToString() это правильно.

Ответ №1:

Я могу неправильно истолковать вашу проблему, но почему бы вам не поместить все, что вы хотите сохранить, в класс и сделать это следующим образом (плюс, если вы используете class, ваши данные «транспортировка» и «управление» будут намного проще) :

СЕРИАЛИЗАЦИЯ

 XmlSerializer serializer = new XmlSerializer(typeof(FrogGameData));
TextWriter textWriter = new StreamWriter("FrogGameSaveFile.xml");
serializer.Serialize(textWriter, _frogGameData);
textWriter.Close();
  

ДЕСЕРИАЛИЗАЦИЯ

 XmlSerializer deserializer = new XmlSerializer(typeof(FrogGameData));
TextReader textReader = new StreamReader("FrogGameSaveFile.xml");
_frogGameData = (FrogGameData)deserializer.Deserialize(textReader);
textReader.Close();
  

Примечание : поле, которое необходимо сохранить, должно иметь свойство, потому что тег в XML будет имитировать имя свойства.

Дополнительное примечание: FrogGameData не отличается от обычного класса для автоматической сериализации, подобной этой. XML будет имитировать порядок ваших свойств в классе для того, который находится в файле XML.

Но если вам нужно изменить расположение тегов XML, вы можете сделать что-то вроде [XmlElement(Order = 1)] , [XmlElement(Order = 2)] , etc поверх вашего свойства, чтобы настроить порядок в файле XML.


Обновить

На случай, если вам это нужно, это пример вашего класса FrogGameData :

 public class FrogGameData
{
    private Frog _frog1;
    private Frog _frog2;

    public Frog Frog1
    {
        get { return _frog1; }
        set { _frog1 = value; }
    }

    public Frog Frog2
    {
        get { return _frog2; }
        set { _frog2 = value; }
    }
}
  

И XML будет в значительной степени похож на это :

 <?xml version="1.0" encoding="utf-8"?>
<FrogGameData>
    <Frog1>Something-depends-on-your-data</Frog1>
    <Frog2>Something-depends-on-your-data</Frog2>
</FrogGameData>
  

Но, если ваш класс (обратите внимание на XmlElement часть) :

 public class FrogGameData
{
    private Frog _frog1;
    private Frog _frog2;

    [XmlElement(Order = 2)]
    public Frog Frog1
    {
        get { return _frog1; }
        set { _frog1 = value; }
    }

    [XmlElement(Order = 1)]
    public Frog Frog2
    {
        get { return _frog2; }
        set { _frog2 = value; }
    }
}
  

Тогда ваш XML будет :

 <?xml version="1.0" encoding="utf-8"?>
<FrogGameData>
    <Frog2>Something-depends-on-your-data</Frog2>
    <Frog1>Something-depends-on-your-data</Frog1>
</FrogGameData>