.NET 3.x Бинарная сериализация класса без подписчиков на его событие - C#
Формулировка задачи:
Здравствуйте.
Продемонстрирую проблему на упрощенном примере.
Есть класс EventingClass, у которого есть события OnSave и OnLoad, на которые подписан класс SubscriberClass.
Когда пытаюсь сериализовать EventingClass, BinaryFormatter находит подписчика на событие и пытается сериализовать его тоже. Поскольку мне не нужно сериализовать SubscriberClass и он не помечен атрибутом Serializable, возникает ошибка сериализации.
Если убрать подписку на события - сериализация проходит успешно. Как быть? Как заставить бинарную сериализацию не проходить по событиям (я сам восстановлю подписки, если нужно)?
Код:
Заранее спасибо.
//EventingClass.cs using System; using System.IO; using System.Runtime.Serialization.Formatters.Binary; namespace SerWithoutSubscribers { public delegate void OnLoadFileEventHandler(object sender, OnLoadFileEventArgs e); public delegate void OnSaveFileEventHandler(object sender, OnSaveFileEventArgs e); [Serializable] public class EventingClass { static BinaryFormatter formatter = new BinaryFormatter(); public EventingClass() { } public int SomeIntValue { get; set; } public virtual void Load(string file_name) { FileStream fs = new FileStream(file_name, FileMode.Open, FileAccess.Read); Load(fs); fs.Close(); } public event OnLoadFileEventHandler OnLoad; public virtual void Load(FileStream fs) { var loaded_ec = (EventingClass)formatter.Deserialize(fs); this.SomeIntValue = loaded_ec.SomeIntValue; if (OnLoad != null) { OnLoad(this, new OnLoadFileEventArgs()); } } public virtual void Save(string file_name, bool isClear = true) { FileMode fm; if (!isClear) { fm = FileMode.Append; } else { fm = FileMode.Create; } FileStream fs = new FileStream(file_name, fm, FileAccess.Write); Save(fs, isClear); fs.Close(); } public event OnSaveFileEventHandler OnSave; public virtual void Save(FileStream fs, bool isClear) { formatter.Serialize(fs, this); if (OnSave != null) { OnSave(this, new OnSaveFileEventArgs(isClear)); } } } }
//SubscribeClass.cs namespace SerWithoutSubscribers { public class SubscribeClass { EventingClass ec; bool is_loaded = false, is_saved = false; public SubscribeClass(EventingClass ec) { this.ec = ec; ec.OnLoad += new OnLoadFileEventHandler(ec_OnLoad); //Комментируем эти 2 строки - работает. ec.OnSave += new OnSaveFileEventHandler(ec_OnSave); //Комментируем эти 2 строки - работает. } public bool IsLoaded { get { return is_loaded; } } public bool IsSaved { get { return is_saved; } } void ec_OnLoad(object sender, OnLoadFileEventArgs e) { is_loaded = true; is_saved = false; } void ec_OnSave(object sender, OnSaveFileEventArgs e) { is_saved = true; is_loaded = false; } } }
//Program.cs using System; namespace SerWithoutSubscribers { class Program { static void Main() { const string file_name = "ec.dat"; var ec = new EventingClass(); var sc = new SubscribeClass(ec); WriteStatus("Before saving.", sc); ec.Save(file_name); WriteStatus("After saving, before loading.", sc); ec.Load(file_name); WriteStatus("After loading.", sc); Console.WriteLine("Press any key to exit..."); } private static void WriteStatus(string mes, SubscribeClass sc) { Console.WriteLine(mes); Console.WriteLine("Is Loaded: {0}", sc.IsLoaded); Console.WriteLine("Is Saved: {0}\n", sc.IsSaved); } } }
//OnLoadFileEventArgs.cs using System; namespace SerWithoutSubscribers { public class OnLoadFileEventArgs : EventArgs { public OnLoadFileEventArgs() : base() { } } }
//OnSaveFileEventArgs.cs using System; namespace SerWithoutSubscribers { public class OnSaveFileEventArgs : EventArgs { bool clearBefore; public OnSaveFileEventArgs(bool clearBefore) : base() { this.clearBefore = clearBefore; } public bool ClearBefore { get { return clearBefore; } } } }
Решение задачи: «.NET 3.x Бинарная сериализация класса без подписчиков на его событие»
textual
Листинг программы
[field: NonSerialized] public event ...
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д