.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 ...