I had always had issue with implementing ICloneable in the .Net Framework on my classes. Implementing ICloneable requires that you return an Object, but a lot of time you don’t want to return an Object type, you want to return a strongly typed object of type whatever.
Well, thanks to a tip I heard on .NetRocks from Rocky Lhotka, I have coded up an example of how you can a) Implement ICloneable, and b) return a strongly typed object from your Clone method.
Imports System
Public Class BusinessObject
Implements ICloneable Private Function privateClone() As Object Implements ICloneable.Clone
Dim MyClone As Object = makeClone()
Return MyClone
End Function Public Function Clone() As BusinessObject
Dim MyClone As BusinessObject = makeClone()
Return MyClone
End Function Private Function makeClone() As BusinessObject
'*** do the clone here
End Function End Class
The trick is to implement ICloneable as a private function. To be honest I have no idea why this works. You would think that implementing the Clone method as a private function would mean that you couldn’t access it, but as the code I wrote below shows, it does work.
imports Microsoft.VisualBasic
imports System
imports System.Collections
public module MyModule
sub Main
RL()
dim o as new BusinessObject
WL("IClone " & o.Clone.IClone)
WL("StandardClone " & o.Clone.StandardClone)
dim i as System.ICloneable
i = ctype(o, System.ICloneable)
WL("IClone " & ctype(i.Clone,BusinessObject).IClone)
WL("StandardClone " & ctype(i.Clone,BusinessObject).StandardClone)
RL()
end sub
#region "Helper methods"
sub WL(text as object)
Console.WriteLine(text)
end sub
sub WL(text as object, paramarray args as object())
Console.WriteLine(text.ToString(), args)
end sub
sub RL()
Console.ReadLine()
end sub
sub Break()
System.Diagnostics.Debugger.Break()
end sub
#end region
end module
public Class BusinessObject
Implements System.ICloneable
public IClone as string = ""
public StandardClone as string = ""
Private Function privateClone() As Object Implements ICloneable.Clone
Dim MyClone As Object = makeClone()
ctype(MyClone,BusinessObject).IClone = "true"
Return MyClone
End Function
Public Function Clone() As BusinessObject
Dim MyClone As BusinessObject = makeClone()
MyClone.StandardClone = "true"
Return MyClone
End Function
Private Function makeClone() As BusinessObject
'*** do the clone here
return new BusinessObject
End Function
End Class
I will have to get to the bottom of this private thing. But at least this will work and do you want expect it to.
Update: I got some answers from a couple people online.
Alvin Bruney (http://msmvps.com/blogs/Alvin/ ) suggested:
The modify tag, private, does not apply to the compiler. It is capable of
calling the method. The tag is applicable only to calling code.
This I knew, but I guess I was wondering why the compiler allows you to do this. I guess it makes sense that the interface makes that method public, so public it is! Case closed