【问题标题】:Serialization of a class with events带有事件的类的序列化
【发布时间】:2012-06-04 17:27:28
【问题描述】:

我有一个这样的课程:

public delegate void ChangedEventHandler(object sender, EventArgs e);
[Serializable]
public class valueDouble
{
    public event ChangedEventHandler Changed;
    public double value
    {
        get { return _value; }
        set 
        {
            _value = value;
            if (Changed != null)
            {
                Changed(this, EventArgs.Empty);
            }
        }
    }
    private double _value = 0;
}

我还有另一个类 (StepPulseblaster),它不可序列化并添加了一个事件处理程序

valDouble.Changed += new ChangedEventHandler(sc_PropertyChanged);

当我尝试序列化 valueDouble 类时,会报错:

The Type StepPulseblaster is not marked as serializable

当我评论该行时

valDouble.Changed += ...

不会再有错误了。

我如何序列化一个连接了一些事件的类?

【问题讨论】:

  • 反序列化时您希望事件仍然存在,还是希望在没有事件的情况下序列化数据?
  • 我使用事件来更新图形用户界面,所以我在反序列化后需要事件。我有这个类的大约 1000 个重复项,所以我真的不想在序列化之前删除事件并重新创建它。
  • 好的,下一个问题:为什么要序列化对象?您是将其存储在某处并稍后重新加载,还是使其可访问不同的上下文(例如,不同的 AppDomain 或不同的进程)?您将无法序列化对您的 GUI 的引用,但根据您的需要,可能有一些简单的方法可以完成您所追求的目标。
  • 我想把它保存到磁盘,以后可以恢复。

标签: c# class events serialization serializable


【解决方案1】:

你应该这样做:

[field: NonSerialized]
public event ChangedEventHandler Changed;

MSDN中所述:

要将 NonSerializedAttribute 类应用于事件,请将属性位置设置为 field

【讨论】:

  • 这很有趣,从来不知道你能做到。
  • 指向the docs 的链接似乎没有任何用处。是否有链接失效?
【解决方案2】:

NonSerialized 属性仅适用于字段,因此要使用它,您必须调整代码以使用字段。

尝试像这样创建您的活动:

[NonSerialized]
private ChangedEventHandler _changed;
public event ChangedEventHandler Changed
{
    add { _changed += value; }
    remove { _changed -= value; }
}

然后在 value 属性中使用字段,而不是属性:

public double value
{
    get { return _value; }
    set 
    {
        _value = value;
        if (_changed != null)
        {
            _changed(this, EventArgs.Empty);
        }
    }
}
private double _value = 0;

【讨论】:

    【解决方案3】:

    要么将 StepPulseBlaster 标记为可序列化,要么使用 XmlIgnore 属性来防止 Changed 被序列化。

    【讨论】:

      【解决方案4】:

      使用[NonSerialized] 属性避免事件序列化。

      【讨论】:

      • 在 VS2010 中,将 [NonSerialized] 应用于事件会报错:“错误 2 属性 'NonSerialized' 在此声明类型上无效。它仅在 'field' 声明上有效。”跨度>
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-07
      • 2017-08-19
      相关资源
      最近更新 更多