When serializing a class with an event, all classes subscribing to that event have to be serializable aswell. Usually you don't have any control over the classes subscribing to that event, or you don't want them to be remoted in the first place.
By adding the NonSerialized attribute to the event, with the field keyword, the field that holds the delegate for the event is stored is not serialized. So those subsribers no longer need to be serializable.
// ===============================================================================// Copyright (C) 2005 Paul van Brenk// All rights reserved.// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR// FITNESS FOR A PARTICULAR PURPOSE.// ==============================================================================// Serializing a class with an event sample.// ==============================================================================using System;namespace Paulb.CodeSnippets{ [Serializable] public class SerializableClass { public SerializableClass() { /// } // adding the NonSerialized attribute this way, // we don't serialize the field where the delegate for this event is stored, // that way those subscribers don't need to be serializable. [field: NonSerialized] public event EventHandler Event; } /// <summary> /// This class can not be serialized, since the serializable attribute is missing. /// </summary> public class NotSerializedClass{ public NotSerializedClass(){ serializable.Event +=new EventHandler(serializable_Event); } private SerializableClass serializable = new SerializableClass(); private void serializable_Event(object sender, EventArgs e) { // handle event here } }}
Some background on how events are compiled from "The C# programming language" p330:
"When compiling a field-like event, the compiler automatically creates storage to hold the delegate and created accessors for the event that add or remove event handlers to the delegate field."
This results in the pseudo code generated for the SerializableClass:
.class public auto ansi serializable beforefieldinit SerializableClassextends object{.event [mscorlib]System.EventHandler Event{// event accessors.addon instance void Paulb.CodeSnippets.SerializableClass::add_Event([mscorlib]System.EventHandler).removeon instance void Paulb.CodeSnippets.SerializableClass::add_Event([mscorlib]System.EventHandler)}.method public hidebysig specialname rtspecialname instance void .ctor() cil managed{}// delegate storage.field private [mscorlib]System.EventHandler Event}
disclaimer: Use at your own risk. This code is not threatsafe. Bugs, omissions let me know.