Почему BinaryFormatter пытается сериализовать событие в классе Serializable?

У меня есть простой класс, который помечен как Serializable, и это событие имеет событие. Я попытался помечать элемент события как NonSerialized, однако компилятор жалуется. Однако, когда я перехожу к сериализации экземпляра класса, BinaryFormatter генерирует исключение, которое событие не сериализуемо. Означает ли это, что вы не можете сериализовать классы с событиями? Если это так, то компилятор должен сказать это заранее.

Stream file = File.Open("f", FileMode.Open);
BinaryFormatter bf = new BinaryFormatter();

object obj = null;
try
{
    obj = bf.Deserialize(file);
}
catch (System.Runtime.Serialization.SerializationException e)
{
    MessageBox.Show("De-Serialization failed : {0}", e.Message);
}
file.Close();

System.Collections.ArrayList nodeList = obj as System.Collections.ArrayList;

foreach (TreeNode node in nodeList)
{
    treeView.Nodes.Add(node);
}

Не удается выполнить работу над следующим классом:

[Serializable()]
class Simple
{
    private int myInt;
    private string myString;
    public event SomeOtherEventDefinedElsewhere TheEvent;

}

Ответ 1

"В случае событий вы также должны добавьте квалификатор атрибута поля, когда применение атрибута NonSerialized так что атрибут применяется к основного делегата, а не само событие"   Расширенная сериализация - MSDN


Префикс NonSerializedAttribute с полем

[field:NonSerialized]
public event MyEventHandler MyEvent;

Ответ 2

Важно помнить, что атрибут [Field:NonSerialized] применяется к делегатам, а не к событиям, чувствительным к регистру кстати, затем реализует объект ISerializable и использует отражение, повторяется через класс, который вы сериализуете, ищите обработчик событий и отмените подписку на события, предшествующие сериализации. Затем, когда вы выполняете десериализацию, вы можете при необходимости автоматически подключать события при десериализации...

Ответ 3

Я знаю, что это поздний пост, но здесь есть реальный ответ на этот вопрос. Создайте ручное добавление/удаление "getters/setters" для вашего события (компилятор делает это за вами за кулисами, но в этом случае вы должны сделать это явно), а затем отметьте свое событие как NonSerialized. У меня нет времени, чтобы вырвать код для вас, но быстрый поиск показывает, кто столкнулся с тем же вопросом:

http://sanity-free.org/113/csharp_binary_serialization_oddities.html

Не используйте эту строку: [MethodImpl (MethodImplOptions.Synchronized)]

Это приводит к проблемам безопасности потока, которые были исправлены в С# 4; см.:

http://blogs.msdn.com/b/cburrows/archive/2010/03/05/events-get-a-little-overhaul-in-c-4-part-i-locks.aspx

Вам нужно будет либо перевернуть свою собственную беззаботную альтернативу (используя CAS), либо выполнить поиск в Интернете по одному; к сожалению, у меня нет времени, поскольку я должен бежать, но вы понимаете.

Надеюсь, это поможет!