I have a question relating to serializing a class that contains events.
Basically I want serialize a class (class1) that publishes an event
(event1). Subscribers to event1 could be any type of class and some of the
subscribers may not be serializable.
My problem is that if I try to serialize an instance of "class1" and that
instance's has subscrubers to "event1" that are not serializable then I get
an error when I call the "Formatter.Serialize()" method.
Since I cannot apply the "[NonSerialized]" attribute to my event (it can
only be applied to fields) I am forced to set "event1" to null before
serializing. This is obviously a
bad solution and whilst I am sure I could come up with a way to save the
list of subscribers before serializing so I could restore it after wards I
wanted to know if there is a good solution to this problem.
Mattias Sj?gren - 08 Oct 2003 23:30 GMT
Anthony,
>Since I cannot apply the "[NonSerialized]" attribute to my event (it can
>only be applied to fields) I am forced to set "event1" to null before
>serializing.
You can if you implement the event accessors yourself
[NonSerialized] private MyEventDelegate _myEvent;
public event MyEventDelegate MyEvent
{
add { ... }
remove { ... }
}
Mattias

Signature
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/
Please reply only to the newsgroup.
Jay B. Harlow [MVP - Outlook] - 09 Oct 2003 04:29 GMT
Anthony,
In addition to Mattias's suggestion, I understand that you can use a field
modifier on the attribute.
> [field: NonSerialized]
> public event EventHandler NameChanged;
For VB.NET the only real options I have found is to implement the
ISerializable interface & explicitly serialize each field or to use a C#
base class that does not serialize the event.
Hope this helps
Jay
> I have a question relating to serializing a class that contains events.
> Basically I want serialize a class (class1) that publishes an event
[quoted text clipped - 11 lines]
> list of subscribers before serializing so I could restore it after wards I
> wanted to know if there is a good solution to this problem.
Pave Husakouski - 09 Oct 2003 10:01 GMT
>Since I cannot apply the "[NonSerialized]" attribute to my event (it can
You can use [field:NonSerialized] instead [NonSerialized]
>only be applied to fields) I am forced to set "event1" to null before
>serializing. This is obviously a
>bad solution and whilst I am sure I could come up with a way to save the
>list of subscribers before serializing so I could restore it after wards I
>wanted to know if there is a good solution to this problem.
There is no good way to deseriaize of events. You should
serialize the list of subscribers and/or metadata for your
events.
It is bad solution to use events and delegates to
[de]serialize objects. You can deserialize event if and
only if all delegates (methods) are public !
So any programmer can invoke this method.
To avoid this hole you should build the class library
whithout using of events at all !
Use the callback interfaces instead delegates and events.
I wrote the explanatory sample:
interface DataModelObjectRemoveCallback
{
void OnBeforeRemove(ref bool bStopIvocation,
CallbackEventargs args);
void OnAfterRemove( CallbackEventargs args);
object Owner{get;}
int Cookie{get;set;}
}
class Class1
{
class DataModelObjectRemove :
DataModelObjectRemoveCallbackImpl
{
void DataModelObjectRemoveCallback.OnBeforeRemove
(ref bool bStopIvocation, CallbackEventargs args)
{
// do something
}
void DataModelObjectRemoveCallback.OnAfterRemove(
CallbackEventargs args);
{
// do something
}
}
DataModelObjectRemove removeHandler=null;
}
class DataModel
{
public bool RemoveAdvise(DataModelObjectRemove target)
{}
public bool RemoveUnadvise(DataModelObjectRemove target)
{}
public void FireRemove(CallbackEventargs argts)
{}
private DataModelObjectRemove [] _arrInvoationList=null;
}
class DataModelObjectRemoveCallbackImpl :
DataModelObjectRemoveCallback
{
public DataModelObjectRemoveCallbackImpl(object owner)
{
_Owner = owner;
}
void DataModelObjectRemoveCallback.OnBeforeRemove(ref
bool bStopIvocation, CallbackEventargs args)
{}
void DataModelObjectRemoveCallback.OnAfterRemove(
CallbackEventargs args)
{}
object DataModelObjectRemoveCallback.Owner{get {return
_Owner;}}
int DataModelObjectRemoveCallback.Cookie
{
get{return _iCookie;}
set{_iCookie = value;};
}
int _iCookie = 0;
object _Owner = null;
}
Regards,