Custom deserialization and CollectionBase

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Hello, I'm writing a custom container class using CollectionBase and I'm having some trouble with implementing the ISerializable interface so I can have some custom handling on serialization. The problem is, in the deserialization constructor, I can't set the InnerList property of the CollectionBase class as its a read only property.

Any ideas?
 
Yes thats a problem but fortunately a solution exists. The trick is to try
and not use CollectionBase, but write a serializable class that works like
CollectionBase.

And as long as you inherit from Collectionbase, it will never work - because
of the very reason you mentioned. Instead if you implement ICollection and
write your own code to do collection-like things, you will be able to make
it work. The trick is, to implement ICollection, and have your own innerlist
instead. That own innerlist, I have tried with a hashtable or an arraylist,
but I feel there are other options too (I've seen a linked list
implementation too).

Anyway, here is some sample code that I know works cuz I'm workin' with it
:) - .

using System;
using System.Collections ;
using System.Runtime.Serialization;

namespace BlaHBlaH
{
/// <summary>
/// Summary description for UsageLogs.
/// </summary>
[Serializable]
public class UsageLogs : ICollection, ISerializable
{
public delegate void DataChangedEventHandler(object sender, EventArgs e) ;
public event DataChangedEventHandler DataChanged ;

private ArrayList InnerList ;

public UsageLogs()
{
InnerList = new ArrayList() ;
}

public int Add(UsageLog usagelog)
{
int returnval = 1 ;
InnerList.Add(usagelog) ;
if (DataChanged != null)
DataChanged(this, new EventArgs()) ;
return returnval ;
}

public void Remove(UsageLog usagelog)
{
InnerList.Remove(usagelog) ;
if (DataChanged != null)
DataChanged(this, new EventArgs()) ;
}

#region ISerializable Members

public void GetObjectData(SerializationInfo info, StreamingContext
context)
{
info.AddValue("UsageLogs_InnerList", InnerList, typeof(ArrayList)) ;
}

public UsageLogs(SerializationInfo info, StreamingContext context)
{
InnerList = (ArrayList)
info.GetValue("UsageLogs_InnerList",typeof(ArrayList)) ;
}
#endregion

#region ICollection Members

public UsageLog this[int index]
{
get{return (UsageLog) InnerList[index];}
}

public int Count
{
get{return InnerList.Count;}
}

public bool IsSynchronized
{
get
{
return false;
}
}

public void CopyTo(Array array, int index)
{
InnerList.CopyTo(array, index);
}

public object SyncRoot
{
get
{
return this;
}
}

#endregion

#region IEnumerable Members

public IEnumerator GetEnumerator()
{
return InnerList.GetEnumerator();
}
#endregion
}
}


If you have a situation in which you are using another variable that
inherits from CollectionBase, rather than directly inheriting from
CollectionBase, you could morph the above class to use Objects instead of
UsageLog.

- Sahil Malik
Independent Consultant
You can reach me thru my blog - http://dotnetjunkies.com/WebLog/sahilmalik/



Scott Crumpler said:
Hello, I'm writing a custom container class using CollectionBase and I'm
having some trouble with implementing the ISerializable interface so I can
have some custom handling on serialization. The problem is, in the
deserialization constructor, I can't set the InnerList property of the
CollectionBase class as its a read only property.
 
Back
Top