commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Schley Andrew Kutz <ak...@lostcreations.com>
Subject [cli] Option class must be serializable in C# port
Date Sat, 26 Apr 2008 22:39:59 GMT
In C# all classes derive from Object, just like Java. Even primitive  
types are automatically boxed and unboxed into Object-derived  
subclasses, just like Java. For a class to be cloneable it must  
implement the interface ICloneable and the method 'public object  
Clone()', just like Java. However, unlike Java, Object does not  
implement a shallow clone method. This means that the logic you  
implement in your own clone method cannot call the super (or base as  
it is in C#) class's Clone method to get a typed, shallow clone. This  
would not necessarily be a big deal as you could just create a new  
class that you are attempting to clone, but if you do this you would  
have to be able to clone its properties (assuming they are publicly  
accessible or can be set via a constructor) manually -- a cumbersome  
task.

You see the problem. Option is cloneable, and it relies on the  
Object's clone method. I toyed around porting this functionality via  
two methods. The first method looked like this:

object clone = Activator.CreateInstance( this.GetType(), null );
( clone as Option ).m_alist_values = new List<string>( m_alist_values );
return clone;

The above code will not work in all cases, hence I discarded it. The  
problem is that the Activator.CreateInstance method's second parameter  
requires either a null value for a parameterless constructor, or a  
parameter array to pass to the constructor of the type you are  
attempting to create. As seen in OptionTest.java (and now  
OptionTest.cs), the DefaultOption class that extends Option does not  
implement a parameterless constructor, and in fact does not even  
override all of  Option's constructors, just one. So, while using the  
CreateInstance method *would* result in the proper object type once  
cloned, it is cumbersome (although possible) to know the right  
constructor parameters to pass to the CreateInstance method. Even if  
you do figure out the parameters needed, you still have the task of  
cloning the new Option's properties, some of which are not publicly  
scoped.

Instead, I am serializing the object to be cloned and deserialzing it  
into a new copy. Like so:

BinaryFormatter bf = new BinaryFormatter();
MemoryStream memStream = new MemoryStream();
bf.Serialize( memStream, this );
memStream.Flush();
memStream.Position = 0;
object clone = ( bf.Deserialize( memStream ) );
( clone as Option ).m_alist_values = new List<string>( m_alist_values );
return clone;

This method is certainly not as efficient as a simple object creation,  
but it guarantees future compatibility with new properties that Option  
may receive. The only caveat is that the Option class, and any class  
that extends it, must implement the attribute [Serializable] so that  
it can be serialized:

[Serializable]
public class MyOption : Option
{
...
}

I think it is a small price to pay for retaining this functionality  
and not pushing any change onto users.

Thoughts?

-- 
-a

"condensing fact from the vapor of nuance"

gpg pubkey:         http://www.lostcreations.com/~akutz/akutz.gpg
lostcreations ca:  http://www.lostcreations.com/lostcreations.com-ca.crt


Mime
View raw message