17

I need to avoid serializing an Event class member because when the event is handled by an object that is not marked as Serializable the serialization will fail.

I tried using the NonSerialized attribute on the Event class member but it fails to compile. This line of code:

<NonSerialized()> Public Event PropertyValueChanged()

produces the following error:

Attribute 'NonSerializedAttribute' cannot be applied to 'PropertyValueChanged' because the attribute is not valid on this declaration type.

Public Event PropertyValueChanged() ' compiles but needs the extra handling described below

Is there another way to avoid serializing Event members?

This is not a problem if the event is not handled and I can work around it by cloning the objects (and ignoring the event) before serializing them. Just wondering if there is a better way.

Thanks.

Paul Sasik
  • 79,492
  • 20
  • 149
  • 189
  • @Paul - re "still fails"; what exactly is it you want to do? I wonder if changing serializer would be a good option here (it isn't as hard as it sounds, and has side benefits too). Up to you of course, but I can talk about this area for *hours*... – Marc Gravell Mar 06 '10 at 09:27
  • @Marc: Thanks for following up. I simply need to ignore events when serializing a class since serialization fails when the event is wired to an object that is not serializable. The NonSerialized attribute makes sense but does not seem to work the same way in VB as in C#... I get a compiler error even when I decorate a backing field to a public event property. What do you mean when you say "changing the serializer"? Do you mean custom serialization or some other, 3rd party library? – Paul Sasik Mar 08 '10 at 13:10

3 Answers3

36

In C# you can do this as below, so I hope this translates identically to VB.

Note this only applies to field-like events (i.e. where you don't have your own add/remove):

[field: NonSerialized]
public event EventType EventName;

Otherwise something like:

[NonSerialized]
EventType backingField;
public event EventType {
    add { backingField += value; }
    remove { backingField -= value; }
}
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • +1 I should have known, that there was going to be no way to beat you to answering this question. – kemiller2002 Mar 05 '10 at 19:31
  • Link to VB.NET discussion and possible workaround: http://www.lhotka.net/WeBlog/CommentView.aspx?guid=776f44e8-aaec-4845-b649-e0d840e6de2c – Paul Sasik Mar 05 '10 at 20:25
  • I implemented the solution in its entire per the link provided above and the serialization still fails. Giving up... My ICloneable workaround will do. – Paul Sasik Mar 05 '10 at 20:36
  • Is there any solution if the event is part of an interface? – findusl Oct 29 '18 at 22:23
  • @findusl `BinaryFormatter` isn't looking at the interface - it is looking at each *object*, and the *fields* on each object. So: no. Frankly, my solution here is usually: "don't use `BinaryFormatter`, it is terrible" – Marc Gravell Oct 29 '18 at 22:32
6

It isn't working because the compiler actually generates a backing field for the event. To enable it, just prefix your attribute with field:

[field: NonSerialized]
public event EventHandler PropertyValueChanged;
Abe Heidebrecht
  • 30,090
  • 7
  • 62
  • 66
0

How I've done it in the past for projects is implement the IXmlSerializable interface and control my serialization manually. I find this makes serializing GUI based controls (with lots of events) much easier.

IXmlSerializable

NebuSoft
  • 3,962
  • 2
  • 22
  • 24