Serialization of SortedList objects when object contains event

D

Dennis C. Drumm

I have a class derived from a SortedList called SystemList that contains a
list of objects indexed with a string value.

The definition of the objects contained in the SortedList have a boolean
field and an event that is fired if the boolean field value changes.

The derived SortedList class has an override for the Add method. The Add
method adds an event handler for the object's event for each new item added
to the list. In the program, the events work fine and all seems well.

However, when I serialize and then try to deserialize the derived
SortedList, deserialization fails. If I rem out the line that adds the event
handler in the Add method, everything serializes and deserializes jsut fine.
But with it in I can't deserialize.

Can someone suggest what is going wrong here and how I can correct it?

Thanks,

Dennis

BTW, the code for the deserialization is:

BinaryFormatter bf = new BinaryFormatter();

bf.AssemblyFormat = FormatterAssemblyStyle.Simple;

IFormatter formatter = bf;

Stream stream = new FileStream(name, FileMode.Open, FileAccess.Read,
FileShare.Read);

systemList = (SystemList)formatter.Deserialize(stream);

fileName = name; // update doc's file name

stream.Close();
 
N

Nicholas Paldino [.NET/C# MVP]

Dennis,

When you have an event, you must store a reference to the target of the
event. In other words, a reference to the object that holds the method to
be called when the event is fired is stored by the object firing the event.

Because of this, when you serialize the object that fires the events, it
tries to serialize the event handlers as well.

To get around this, you will have to disconnect the event handlers, or
you could flag the event with the NonSerialized attribute (I am not sure if
that works). Either way, you have to prevent the event handlers from being
serialized.

Hope this helps.
 
D

Dennis C. Drumm

Nickolas:

I thought so, but trying the NonSerialize attribute does not work. That can
only be used on fields.

How do I remove/disconnect the event handlers? I would think -= but the
compiler doesn't like that.

Alternatively, is there a way to override the deserialization process and
add do something with the event handlers at that point?

Dennis

Nicholas Paldino said:
Dennis,

When you have an event, you must store a reference to the target of the
event. In other words, a reference to the object that holds the method to
be called when the event is fired is stored by the object firing the event.

Because of this, when you serialize the object that fires the events, it
tries to serialize the event handlers as well.

To get around this, you will have to disconnect the event handlers, or
you could flag the event with the NonSerialized attribute (I am not sure if
that works). Either way, you have to prevent the event handlers from being
serialized.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Dennis C. Drumm said:
I have a class derived from a SortedList called SystemList that contains a
list of objects indexed with a string value.

The definition of the objects contained in the SortedList have a boolean
field and an event that is fired if the boolean field value changes.

The derived SortedList class has an override for the Add method. The Add
method adds an event handler for the object's event for each new item added
to the list. In the program, the events work fine and all seems well.

However, when I serialize and then try to deserialize the derived
SortedList, deserialization fails. If I rem out the line that adds the event
handler in the Add method, everything serializes and deserializes jsut fine.
But with it in I can't deserialize.

Can someone suggest what is going wrong here and how I can correct it?

Thanks,

Dennis

BTW, the code for the deserialization is:

BinaryFormatter bf = new BinaryFormatter();

bf.AssemblyFormat = FormatterAssemblyStyle.Simple;

IFormatter formatter = bf;

Stream stream = new FileStream(name, FileMode.Open, FileAccess.Read,
FileShare.Read);

systemList = (SystemList)formatter.Deserialize(stream);

fileName = name; // update doc's file name

stream.Close();
 
N

Nicholas Paldino [.NET/C# MVP]

Dennis,

If that is the case, then declare your event like this:

// Declare the field that holds the delegate.
[NonSerializable]
private EventHandler mobjEventHandlers = null;

// Declare the event.
public event EventHandler MyEvent
{
add
{
// Just add the event.
mobjEventHandlers += value;
}
remove
{
// Just remove the event.
mobjEventHandlers -= value;
}
}

And that should work.

If you use custom serialization, then you can set which values are
persisted.

Hope this helps.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Dennis C. Drumm said:
Nickolas:

I thought so, but trying the NonSerialize attribute does not work. That can
only be used on fields.

How do I remove/disconnect the event handlers? I would think -= but the
compiler doesn't like that.

Alternatively, is there a way to override the deserialization process and
add do something with the event handlers at that point?

Dennis

message news:[email protected]...
Dennis,

When you have an event, you must store a reference to the target of the
event. In other words, a reference to the object that holds the method to
be called when the event is fired is stored by the object firing the event.

Because of this, when you serialize the object that fires the
events,
it
tries to serialize the event handlers as well.

To get around this, you will have to disconnect the event handlers, or
you could flag the event with the NonSerialized attribute (I am not sure if
that works). Either way, you have to prevent the event handlers from being
serialized.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Dennis C. Drumm said:
I have a class derived from a SortedList called SystemList that
contains
 
D

Dennis C. Drumm

Thanks Nicholas,

Your comments are much appreciated!

Dennis


Nicholas Paldino said:
Dennis,

If that is the case, then declare your event like this:

// Declare the field that holds the delegate.
[NonSerializable]
private EventHandler mobjEventHandlers = null;

// Declare the event.
public event EventHandler MyEvent
{
add
{
// Just add the event.
mobjEventHandlers += value;
}
remove
{
// Just remove the event.
mobjEventHandlers -= value;
}
}

And that should work.

If you use custom serialization, then you can set which values are
persisted.

Hope this helps.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Dennis C. Drumm said:
Nickolas:

I thought so, but trying the NonSerialize attribute does not work. That can
only be used on fields.

How do I remove/disconnect the event handlers? I would think -= but the
compiler doesn't like that.

Alternatively, is there a way to override the deserialization process and
add do something with the event handlers at that point?

Dennis

message news:[email protected]... of
the
method
to events,
handlers,
or
you could flag the event with the NonSerialized attribute (I am not
sure
if
that works). Either way, you have to prevent the event handlers from being
serialized.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

I have a class derived from a SortedList called SystemList that
contains
a
list of objects indexed with a string value.

The definition of the objects contained in the SortedList have a boolean
field and an event that is fired if the boolean field value changes.

The derived SortedList class has an override for the Add method. The Add
method adds an event handler for the object's event for each new item
added
to the list. In the program, the events work fine and all seems well.

However, when I serialize and then try to deserialize the derived
SortedList, deserialization fails. If I rem out the line that adds the
event
handler in the Add method, everything serializes and deserializes jsut
fine.
But with it in I can't deserialize.

Can someone suggest what is going wrong here and how I can correct it?

Thanks,

Dennis

BTW, the code for the deserialization is:

BinaryFormatter bf = new BinaryFormatter();

bf.AssemblyFormat = FormatterAssemblyStyle.Simple;

IFormatter formatter = bf;

Stream stream = new FileStream(name, FileMode.Open, FileAccess.Read,
FileShare.Read);

systemList = (SystemList)formatter.Deserialize(stream);

fileName = name; // update doc's file name

stream.Close();
 
J

Jay B. Harlow [MVP - Outlook]

Dennis,
Alternative to the event procedures as Nicholas showed, you can use the
field attribute modifier:

[field: NonSerialized]
public event EventHandler MyEvent;

Hope this helps
Jay

Dennis C. Drumm said:
Nickolas:

I thought so, but trying the NonSerialize attribute does not work. That can
only be used on fields.

How do I remove/disconnect the event handlers? I would think -= but the
compiler doesn't like that.

Alternatively, is there a way to override the deserialization process and
add do something with the event handlers at that point?

Dennis

message news:[email protected]...
Dennis,

When you have an event, you must store a reference to the target of the
event. In other words, a reference to the object that holds the method to
be called when the event is fired is stored by the object firing the event.

Because of this, when you serialize the object that fires the
events,
it
tries to serialize the event handlers as well.

To get around this, you will have to disconnect the event handlers, or
you could flag the event with the NonSerialized attribute (I am not sure if
that works). Either way, you have to prevent the event handlers from being
serialized.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Dennis C. Drumm said:
I have a class derived from a SortedList called SystemList that
contains
 
J

Jeffrey Tan[MSFT]

Hi Dennis,

Is your problem resolved?
If there is still any problem, please feel free to let me know.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
| Reply-To: "Dennis C. Drumm" <[email protected]>
| From: "Dennis C. Drumm" <[email protected]>
| References: <[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
| Subject: Re: Serialization of SortedList objects when object contains
event
| Date: Wed, 15 Oct 2003 14:17:42 -0400
| Lines: 157
| X-Priority: 3
| X-MSMail-Priority: Normal
| X-Newsreader: Microsoft Outlook Express 6.00.2800.1158
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
| Message-ID: <eYt#[email protected]>
| Newsgroups: microsoft.public.dotnet.languages.csharp
| NNTP-Posting-Host: 206-15-137-36.dialup.ziplink.net 206.15.137.36
| Path: cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP10.phx.gbl
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:191603
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
|
| Thanks Nicholas,
|
| Your comments are much appreciated!
|
| Dennis
|
|
in
| message | > Dennis,
| >
| > If that is the case, then declare your event like this:
| >
| > // Declare the field that holds the delegate.
| > [NonSerializable]
| > private EventHandler mobjEventHandlers = null;
| >
| > // Declare the event.
| > public event EventHandler MyEvent
| > {
| > add
| > {
| > // Just add the event.
| > mobjEventHandlers += value;
| > }
| > remove
| > {
| > // Just remove the event.
| > mobjEventHandlers -= value;
| > }
| > }
| >
| > And that should work.
| >
| > If you use custom serialization, then you can set which values are
| > persisted.
| >
| > Hope this helps.
| >
| > --
| > - Nicholas Paldino [.NET/C# MVP]
| > - (e-mail address removed)
| >
| > | > > Nickolas:
| > >
| > > I thought so, but trying the NonSerialize attribute does not work.
That
| > can
| > > only be used on fields.
| > >
| > > How do I remove/disconnect the event handlers? I would think -= but
the
| > > compiler doesn't like that.
| > >
| > > Alternatively, is there a way to override the deserialization process
| and
| > > add do something with the event handlers at that point?
| > >
| > > Dennis
| > >
| > > "Nicholas Paldino [.NET/C# MVP]" <[email protected]>
wrote
| > in
| > > message | > > > Dennis,
| > > >
| > > > When you have an event, you must store a reference to the target
| of
| > > the
| > > > event. In other words, a reference to the object that holds the
| method
| > to
| > > > be called when the event is fired is stored by the object firing the
| > > event.
| > > >
| > > > Because of this, when you serialize the object that fires the
| > events,
| > > it
| > > > tries to serialize the event handlers as well.
| > > >
| > > > To get around this, you will have to disconnect the event
| handlers,
| > or
| > > > you could flag the event with the NonSerialized attribute (I am not
| sure
| > > if
| > > > that works). Either way, you have to prevent the event handlers
from
| > > being
| > > > serialized.
| > > >
| > > > Hope this helps.
| > > >
| > > >
| > > > --
| > > > - Nicholas Paldino [.NET/C# MVP]
| > > > - (e-mail address removed)
| > > >
| > > > | > > > > I have a class derived from a SortedList called SystemList that
| > contains
| > > a
| > > > > list of objects indexed with a string value.
| > > > >
| > > > > The definition of the objects contained in the SortedList have a
| > > boolean
| > > > > field and an event that is fired if the boolean field value
changes.
| > > > >
| > > > > The derived SortedList class has an override for the Add method.
The
| > Add
| > > > > method adds an event handler for the object's event for each new
| item
| > > > added
| > > > > to the list. In the program, the events work fine and all seems
| well.
| > > > >
| > > > > However, when I serialize and then try to deserialize the derived
| > > > > SortedList, deserialization fails. If I rem out the line that adds
| the
| > > > event
| > > > > handler in the Add method, everything serializes and deserializes
| jsut
| > > > fine.
| > > > > But with it in I can't deserialize.
| > > > >
| > > > > Can someone suggest what is going wrong here and how I can correct
| it?
| > > > >
| > > > > Thanks,
| > > > >
| > > > > Dennis
| > > > >
| > > > > BTW, the code for the deserialization is:
| > > > >
| > > > > BinaryFormatter bf = new BinaryFormatter();
| > > > >
| > > > > bf.AssemblyFormat = FormatterAssemblyStyle.Simple;
| > > > >
| > > > > IFormatter formatter = bf;
| > > > >
| > > > > Stream stream = new FileStream(name, FileMode.Open,
FileAccess.Read,
| > > > > FileShare.Read);
| > > > >
| > > > > systemList = (SystemList)formatter.Deserialize(stream);
| > > > >
| > > > > fileName = name; // update doc's file name
| > > > >
| > > > > stream.Close();
| > > > >
| > > > >
| > > >
| > > >
| > >
| > >
| >
| >
|
|
|
 
D

Dennis C. Drumm

Thank you all! The problem has been resolved.

For any MS people that might be monitoring this thread, the VS.NET and MSDN
Library could use a little more content on how to add and remove event
handlers (and probably event handlers in general). There certainly is some
useful information in them, probably enough for some, but not enough for
anyone just getting familiar with the concept.

Thanks again,

Dennis


Jay B. Harlow said:
Dennis,
Alternative to the event procedures as Nicholas showed, you can use the
field attribute modifier:

[field: NonSerialized]
public event EventHandler MyEvent;

Hope this helps
Jay

Dennis C. Drumm said:
Nickolas:

I thought so, but trying the NonSerialize attribute does not work. That can
only be used on fields.

How do I remove/disconnect the event handlers? I would think -= but the
compiler doesn't like that.

Alternatively, is there a way to override the deserialization process and
add do something with the event handlers at that point?

Dennis

message news:[email protected]... of
the
method
to events,
handlers,
or
you could flag the event with the NonSerialized attribute (I am not
sure
if
that works). Either way, you have to prevent the event handlers from being
serialized.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

I have a class derived from a SortedList called SystemList that
contains
a
list of objects indexed with a string value.

The definition of the objects contained in the SortedList have a boolean
field and an event that is fired if the boolean field value changes.

The derived SortedList class has an override for the Add method. The Add
method adds an event handler for the object's event for each new item
added
to the list. In the program, the events work fine and all seems well.

However, when I serialize and then try to deserialize the derived
SortedList, deserialization fails. If I rem out the line that adds the
event
handler in the Add method, everything serializes and deserializes jsut
fine.
But with it in I can't deserialize.

Can someone suggest what is going wrong here and how I can correct it?

Thanks,

Dennis

BTW, the code for the deserialization is:

BinaryFormatter bf = new BinaryFormatter();

bf.AssemblyFormat = FormatterAssemblyStyle.Simple;

IFormatter formatter = bf;

Stream stream = new FileStream(name, FileMode.Open, FileAccess.Read,
FileShare.Read);

systemList = (SystemList)formatter.Deserialize(stream);

fileName = name; // update doc's file name

stream.Close();
 
J

Jeffrey Tan[MSFT]

Hi Dennis,

Thanks for your feedback.
I am glad your problem has been resolved.
The customer's suggestion will greatly improve our product.

I think you can provide your suggestion to:
http://register.microsoft.com/mswish/suggestion.asp
or email to: (e-mail address removed)

Again, thanks for your information.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
| Reply-To: "Dennis C. Drumm" <[email protected]>
| From: "Dennis C. Drumm" <[email protected]>
| References: <[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
| Subject: Re: Serialization of SortedList objects when object contains
event
| Date: Thu, 16 Oct 2003 05:43:46 -0400
| Lines: 139
| X-Priority: 3
| X-MSMail-Priority: Normal
| X-Newsreader: Microsoft Outlook Express 6.00.2800.1158
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
| Message-ID: <[email protected]>
| Newsgroups: microsoft.public.dotnet.languages.csharp
| NNTP-Posting-Host: 206-15-137-92.dialup.ziplink.net 206.15.137.92
| Path: cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP11.phx.gbl
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:191748
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
|
| Thank you all! The problem has been resolved.
|
| For any MS people that might be monitoring this thread, the VS.NET and
MSDN
| Library could use a little more content on how to add and remove event
| handlers (and probably event handlers in general). There certainly is some
| useful information in them, probably enough for some, but not enough for
| anyone just getting familiar with the concept.
|
| Thanks again,
|
| Dennis
|
|
message
| | > Dennis,
| > Alternative to the event procedures as Nicholas showed, you can use the
| > field attribute modifier:
| >
| > [field: NonSerialized]
| > public event EventHandler MyEvent;
| >
| > Hope this helps
| > Jay
| >
| > | > > Nickolas:
| > >
| > > I thought so, but trying the NonSerialize attribute does not work.
That
| > can
| > > only be used on fields.
| > >
| > > How do I remove/disconnect the event handlers? I would think -= but
the
| > > compiler doesn't like that.
| > >
| > > Alternatively, is there a way to override the deserialization process
| and
| > > add do something with the event handlers at that point?
| > >
| > > Dennis
| > >
| > > "Nicholas Paldino [.NET/C# MVP]" <[email protected]>
wrote
| > in
| > > message | > > > Dennis,
| > > >
| > > > When you have an event, you must store a reference to the target
| of
| > > the
| > > > event. In other words, a reference to the object that holds the
| method
| > to
| > > > be called when the event is fired is stored by the object firing the
| > > event.
| > > >
| > > > Because of this, when you serialize the object that fires the
| > events,
| > > it
| > > > tries to serialize the event handlers as well.
| > > >
| > > > To get around this, you will have to disconnect the event
| handlers,
| > or
| > > > you could flag the event with the NonSerialized attribute (I am not
| sure
| > > if
| > > > that works). Either way, you have to prevent the event handlers
from
| > > being
| > > > serialized.
| > > >
| > > > Hope this helps.
| > > >
| > > >
| > > > --
| > > > - Nicholas Paldino [.NET/C# MVP]
| > > > - (e-mail address removed)
| > > >
| > > > | > > > > I have a class derived from a SortedList called SystemList that
| > contains
| > > a
| > > > > list of objects indexed with a string value.
| > > > >
| > > > > The definition of the objects contained in the SortedList have a
| > > boolean
| > > > > field and an event that is fired if the boolean field value
changes.
| > > > >
| > > > > The derived SortedList class has an override for the Add method.
The
| > Add
| > > > > method adds an event handler for the object's event for each new
| item
| > > > added
| > > > > to the list. In the program, the events work fine and all seems
| well.
| > > > >
| > > > > However, when I serialize and then try to deserialize the derived
| > > > > SortedList, deserialization fails. If I rem out the line that adds
| the
| > > > event
| > > > > handler in the Add method, everything serializes and deserializes
| jsut
| > > > fine.
| > > > > But with it in I can't deserialize.
| > > > >
| > > > > Can someone suggest what is going wrong here and how I can correct
| it?
| > > > >
| > > > > Thanks,
| > > > >
| > > > > Dennis
| > > > >
| > > > > BTW, the code for the deserialization is:
| > > > >
| > > > > BinaryFormatter bf = new BinaryFormatter();
| > > > >
| > > > > bf.AssemblyFormat = FormatterAssemblyStyle.Simple;
| > > > >
| > > > > IFormatter formatter = bf;
| > > > >
| > > > > Stream stream = new FileStream(name, FileMode.Open,
FileAccess.Read,
| > > > > FileShare.Read);
| > > > >
| > > > > systemList = (SystemList)formatter.Deserialize(stream);
| > > > >
| > > > > fileName = name; // update doc's file name
| > > > >
| > > > > stream.Close();
| > > > >
| > > > >
| > > >
| > > >
| > >
| > >
| >
| >
|
|
|
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top