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

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

12   голосов , оценка 4.167 из 5
Похожие ответы