D
D
Dmitry Gavrilenko2015-01-23 20:17:13
.NET
Dmitry Gavrilenko, 2015-01-23 20:17:13

What are the requirements of .NET for standard serialization?

What are the requirements of .NET for standard serialization?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Alexey Nemiro, 2015-01-23
@Maddox

In order for a class to be serializable, it must be marked with the [Serializable] attribute .

[Serializable]
public class MyClass 
{
}

The [Serializable] attribute must also have all types that are included in the class. If any of the types does not have this attribute, then when trying to serialize, an exception will be thrown. This is the minimum that is needed.
Binary serialization uses the BinaryFormatter class .
// данные, которые будем сериализовать
var data = new List<int> { 1, 2, 3 };

// выполняем сериализацию 
// в MemoryStream (можно в любой Stream)
var bf = new BinaryFormatter();
var m = new MemoryStream();
bf.Serialize(m, data);
            
// курсор потока переводим в начало, т.к. мы работали с потоком выше
// если открывать новый поток, то это делать не обязательно
m.Position = 0;
// выполняем десериализацию данных из MemoryStream
var result = (List<int>)bf.Deserialize(m);

// выводим результат в консоль
result.ForEach(itm => Console.WriteLine(itm));

If an object comes across a type that is not marked with the [Serializable] attribute , then you can implement the ISerializable interface in the class . Or make a separate class for this type that implements the ISerializable interface . At the same time, do not forget about the [Serializable] attribute , which must be present.
When implementing the ISerializable interface , the class must define the GetObjectData method , which will prepare the data for serialization. And also implement a constructor overload to accept serialized data.
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
  if (info == null)
  {
    throw new ArgumentNullException("info");
  }
  info.AddValue("Ключ", "Значение");
  info.AddValue("Ключ2", this.ИмяСвойства); 
  // и т.д.
}

// конструктор
protected ИмяКласса(SerializationInfo info, StreamingContext context)
{
  if (info == null)
  {
    throw new ArgumentNullException("info");
  }
  this.Свойство = info.GetValue("Ключ", typeof(типДанных));
  this.ИмяСвойства = (string)info.GetValue("Ключ2", typeof(string));
  // и т.д.
}

A common question is how to serialize a Dictionary<TKey, TValue> . Based on all of the above, you can make the following class:
[Serializable]
public class MyDictionary : Dictionary<string, object>, ISerializable
{

  public MyDictionary() { }

  protected MyDictionary(SerializationInfo info, StreamingContext context)
  {
    if (info == null)
    {
      throw new ArgumentNullException("info");
    }
    int count = info.GetInt32("Count"); // получаем число элементов
    for (int i = 0; i < count; i++) // перебираем элементы
    {
      // получаем ключ и значение по индексу элемента
      string key = info.GetString(String.Format("ItemKey{0}", i));
      object value = info.GetValue(String.Format("ItemValue{0}", i), typeof(object));
      // добавляем элемент в себя
      this.Add(key, value);
    }
  }

  public void GetObjectData(SerializationInfo info, StreamingContext context)
  {
    if (info == null)
    {
      throw new ArgumentNullException("info");
    }
    // перебираем все элементы коллекции
    int i = 0;
    foreach (KeyValuePair<string, object> item in this)
    {
      // добавляем отдельно ключ и значение
      info.AddValue(String.Format("ItemKey{0}", i), item.Key, typeof(string));
      info.AddValue(String.Format("ItemValue{0}", i), item.Value);
      i++;
    }
    // запоминаем, сколько всего элементов
    info.AddValue("Count", this.Count);
  }
}

Usage example:
// выполняем сериализацию коллекции
var data = new MyDictionary();
data.Add("Key", "Value");
data.Add("Key2", "Value2");
data.Add("Key3", 123);

var bf = new BinaryFormatter();
var m = new MemoryStream();
bf.Serialize(m, data);

// выполняем десериализацию
m.Position = 0;
var result = (MyDictionary)bf.Deserialize(m);

// выводим результат
foreach (var item in result)
{
  Console.WriteLine("{0} = {1}", item.Key, item.Value);
}

See the .NET Fiddle for how it works .

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question