2010-03-04 3 views
6

Класс, помеченный как [DataContract], не может быть ISerializable одновременно. Хорошо, так как я могу сериализовать этот тип объекта на двоичный поток?.NET: Как бинарно сериализовать объект с атрибутом [DataContract]?

private byte[] GetRoomAsBinary(Room room) 
     { 
      MemoryStream stream = new MemoryStream(); 
      BinaryFormatter bf = new BinaryFormatter(); 
      bf.Serialize(stream, room); 
      return stream.ToArray(); 
     } 

Я не могу заставить его работать без помещения ISerializable. Как я могу получить массив байтов из объекта другим способом?

ответ

3

Решение заключается в использовании DataContractSerializer для сериализации объекта.

+0

'DataContractSerializer' генерирует и читает XML. И XML не является двоичным. – picrap

0

Это принцип двоичной сериализации: только классы [Serializable] могут быть сериализованы (хотя, возможно, я прочитал, что это ограничение было отменено недавно). Если вы хотите взять под контроль процесс сериализации, выполните ISerializable.

Если класс комнаты имеет несериализуемые элементы, вам также понадобится ISerializable.

Что представляют собой члены комнаты?

+0

, как я уже писал, вы не можете иметь класс, который является сериализацией и DataContract в то же время. это порождает исключение во время выполнения – agnieszka

+0

Вы правы, я неправильно понял вопрос. – Timores

+0

Допустимо ли иметь экземпляр класса Room, скажем, RoomProxy с теми же членами, сериализуемый, но не задействованный в DataContract? Во избежание дублирования можно иметь подкласс комнаты, который не помечен как [DataContract]; он может быть сериализован путем внедрения ISerializable. – Timores

24

Код для сериализации и десериализации двоичного форматировщик:

public static class BinarySerializer 
{ 
    public static byte[] Serialize<T>(T obj) 
    { 
     var serializer = new DataContractSerializer(typeof(T)); 
     var stream = new MemoryStream(); 
     using (var writer = 
      XmlDictionaryWriter.CreateBinaryWriter(stream)) 
     { 
      serializer.WriteObject(writer, obj); 
     } 
     return stream.ToArray(); 
    } 

    public static T Deserialize<T>(byte[] data) 
    { 
     var serializer = new DataContractSerializer(typeof(T)); 
     using (var stream = new MemoryStream(data)) 
     using (var reader = 
      XmlDictionaryReader.CreateBinaryReader(
       stream, XmlDictionaryReaderQuotas.Max)) 
     { 
      return (T)serializer.ReadObject(reader); 
     } 
    } 
} 

Использование:

public void TestBinarySerialization() 
{ 
    // Create the person object. 
    Person person = new Person { Name = "John", Age = 32 }; 

    // Serialize and deserialize the person object. 
    byte[] data = BinarySerializer.Serialize<Person>(person); 
    Person newPerson = BinarySerializer.Deserialize<Person>(data); 

    // Assert the properties in the new person object. 
    Debug.Assert(newPerson.Age == 32); 
    Debug.Assert(newPerson.Name == "John"); 
} 
Смежные вопросы