all groups > vb.net > january 2005 >
You're in the vb.net group:
Option Strict and late binding problem
vb.net:
I think I've done my homework and checked around on Google Groups but this seems to be a situation not yet covered. Here is the scenario... There are two classes, Foo and Bar (actually there are more than two classes involved but two will suffice to explain the problem), and each class has a Copy() method as follows: Public Function Copy() As Object Implements ICloneable.Clone ' returns a copy of a Foo object End Function Public Function Copy() As Object Implements ICloneable.Clone ' returns a copy of a Bar object End Function I have another class that subclasses ArrayList. This class allows the list to contain Foo and Bar objects. With me so far? Here comes the kicker... I then iterate over the ArrayList as follows making a copy of the array list: Dim objekt, objcopy As Object For Each objekt In myArrayListInstance objcopy = objekt.Copy() ' Each objekt is either a Foo object or a Bar object ' build another ArrayList with copies of all objects from the original ArrayList Next With 'Option Strict On' this produces a compiler error. How can I achieve this kind of polymorphism with 'Option Strict On' ? Thanks for your consideration, Daniel Klein
Can you use an abstact base class and then derive your other classes from it to get polymorphism? Public MustInherit Class FooBarBase Public MustOverride Function Clone() As FooBarBase End Class Public Class Foo Inherits FooBarBase Public MyString As String Public Overrides Function Clone() As FooBarBase 'Code to create a copy of Foo and return it End Function End Class Public Class Bar Inherits FooBarBase Public MyString As String Public Overrides Function Clone() As FooBarBase 'Code to create a copy of Bar and return it End Function End Class Private Sub Button1_Click(...) Handles Button1.Click Dim al As New ArrayList Dim f1 As New Foo f1.MyString = "F1" Dim b1 As New Bar b1.MyString = "B1" Dim f2 As New Foo f2.MyString = "F2" Dim b2 As New Bar b2.MyString = "B2" al.Add(f1) al.Add(b1) al.Add(f2) al.Add(b2) Dim al2 As New ArrayList For Each fb As FooBarBase In al al2.Add(fb.Clone()) Next For Each fb As FooBarBase In al2 If fb.GetType Is GetType(Foo) Then MsgBox("fb is a Foo: " & DirectCast(fb, Foo).MyString) Else MsgBox("fb is a Bar: " & DirectCast(fb, Bar).MyString) End If Next End Sub Then your arraylist class could be strongly typed to hold foobarbase objects. Will this work for you? Chris
I just put the if statement in to show that the correct Clone method was being called. Look at the loop that clones the object: For Each fb As FooBarBase In al al2.Add(fb.Clone()) Next Notice that there is no if then clause here and the correct .clone method depending on the object is called and the correct copy returned.
The IClonable.Clone() example shown earlier is exactly what you need, but if you can't see how calling Clone() actually calls Copy() through explicit interface implementation then you can create your own interface and use it as follows Interface ICopiable Function Copy() As Object End Interface Class Foo Implements ICopiable Function Copy() Implements ICopiable.Copy ... End Function End Class Class Bar Implements ICopiable Function Copy() Implements ICopiable.Copy ... End Function End Class Sub Test() Dim al As New ArrayList al.Add(new Foo) al.Add(new Bar) For Each obj as ICopiable in al Dim newObj = obj.Copy() Next End Sub Of course since all the Copy methods you mentioned already implement IClonable.Clone, then calling Clone is the exact same thing, but if using a custom ICopiable interface is somehow cleaner or more understandable, then use that. But don't knock .NET's OOD techniques when you don't understand how to use them. Best regards, Sam [quoted text, click to view] > >Sorry, but no...at least not in this manner :-( > >I thought the purpose of polymorphism was to eliminate cumbersome if/then >logic. Besides, there are more classes that implement the Copy() method, >which means the if/then logic would have to be modifed every time a new >class was created that implements the Copy() method. This goes against the >grain of OOD techniques. > >I still maintain that late binding is the only solution to 'pure' >polymorphic behavior such as this. > >Daniel Klein >Cuyahoga Falls, OH
[quoted text, click to view] "Daniel Klein" <danielkleinad@hotmail.com> wrote in message news:k59tv05agol2hp6ashjmc174r73ssir9cu@4ax.com... > With 'Option Strict On' this produces a compiler error. > How can I achieve this kind of polymorphism ... ?
"Object" isn't half as useful as you might think - always try to get at a proper type when manipulating objects and, since both (all?) of your classes implement IClonable, that's as good a type as any when you need to use them, as in : For Each objekt As IClonable In myArrayListInstance objcopy = objekt.Clone() ' returns either Foo or Bar ' build another ArrayList with copies NewArrayList.Add( objekt ) Next HTH, Phill W.
Mttias, Thank you for the cortesy of your reply. Unfortunately, this won't work. Each of the Copy() methods is doing a bit more than what Object.Clone() is doing, which is the reason for creating my own implementation. And each of the Copy() methods cannot be refactored to a common implementation. Besides, this problem address a more generic one of how to achieve true polymorphism without late binding. Any other ideas are welcome. Daniel Klein Cuyahoga Falls, OH On Tue, 01 Feb 2005 01:46:03 +0100, Mattias Sjögren [quoted text, click to view] <mattias.dont.want.spam@mvps.org> wrote: >>How can I achieve this kind of polymorphism with 'Option Strict On' ? > >For Each objekt As ICloneable In myArrayListInstance > objcopy = objekt.Clone() > > > >Mattias
On Tue, 1 Feb 2005 12:28:36 -0000, "Phill. W" [quoted text, click to view] <P.A.Ward@o-p-e-n-.-a-c-.-u-k> wrote: >"Daniel Klein" <danielkleinad@hotmail.com> wrote in message >news:k59tv05agol2hp6ashjmc174r73ssir9cu@4ax.com... > >> With 'Option Strict On' this produces a compiler error. >> How can I achieve this kind of polymorphism ... ? > >"Object" isn't half as useful as you might think - always try to get at >a proper type when manipulating objects and, since both (all?) of >your classes implement IClonable, that's as good a type as any when >you need to use them, as in : > >For Each objekt As IClonable In myArrayListInstance > objcopy = objekt.Clone() ' returns either Foo or Bar > ' build another ArrayList with copies > NewArrayList.Add( objekt ) >Next > >HTH, > Phill W.
Good answer Phil, and it would work if all I was using was the Clone() method, but the Copy() method in each class is doing more than just 'cloning'. It looks like this is one place where 'late binding' will have to do.
Daniel, [quoted text, click to view] >Unfortunately, this won't work. Each of the Copy() methods is doing a bit >more than what Object.Clone() is doing, which is the reason for creating my >own implementation.
As long as the Copy method Implements ICloneable.Clone, the same method is called. So the same work is done. [quoted text, click to view] >Besides, this problem address a more generic one of how to achieve true >polymorphism without late binding.
Interface implementation or deriving from a common base class with virtual methods are great ways of accomplishing that. Mattias -- Mattias Sjögren [MVP] mattias @ mvps.org http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
[quoted text, click to view] On 1 Feb 2005 06:37:38 -0800, "Chris Dunaway" <dunawayc@gmail.com> wrote: >Can you use an abstact base class and then derive your other classes >from it to get polymorphism? > [snip] > >For Each fb As FooBarBase In al2 >If fb.GetType Is GetType(Foo) Then >MsgBox("fb is a Foo: " & DirectCast(fb, Foo).MyString) >Else >MsgBox("fb is a Bar: " & DirectCast(fb, Bar).MyString) >End If >Next > >End Sub > >Then your arraylist class could be strongly typed to hold foobarbase >objects. > >Will this work for you? >
Sorry, but no...at least not in this manner :-( I thought the purpose of polymorphism was to eliminate cumbersome if/then logic. Besides, there are more classes that implement the Copy() method, which means the if/then logic would have to be modifed every time a new class was created that implements the Copy() method. This goes against the grain of OOD techniques. I still maintain that late binding is the only solution to 'pure' polymorphic behavior such as this. Daniel Klein
The thing is, ICloneable.Clone() and Copy() are the exact same method. When you declare Function Copy() As Object Implements ICloneable.Clone Then you can execute this method via obj.Copy() or DirectCast(obj, ICloneable).Clone() And it calls the exact same method. This is called explicit interface implementation where you're implementing an interface method but internally using a different method name. This way when the object is declared as the type that defined it, "Clone" is not accessible, but "Copy" is. But you can cast it to ICloneable and then "Clone" is accessible. But no matter what you do, it calls the exact same code, the contents of the function. Sam On Wed, 02 Feb 2005 15:13:18 GMT, Daniel Klein [quoted text, click to view] <danielkleinad@hotmail.com> wrote: >IClonaeable.Clone() will never work in this instance due the the 'extra >work' the Copy() methods have to do. However the ICopiable solution has >possibilities, I'll let you know. Thanks. > >What I was 'knocking' was the if/then logic, not .NET. Apology accepted ;-) > >Dan
IClonaeable.Clone() will never work in this instance due the the 'extra work' the Copy() methods have to do. However the ICopiable solution has possibilities, I'll let you know. Thanks. What I was 'knocking' was the if/then logic, not .NET. Apology accepted ;-) Dan On Tue, 01 Feb 2005 12:22:16 -0500, Samuel R. Neff [quoted text, click to view] <blinex@newsgroup.nospam> wrote: > >The IClonable.Clone() example shown earlier is exactly what you need, >but if you can't see how calling Clone() actually calls Copy() through >explicit interface implementation then you can create your own >interface and use it as follows > >Interface ICopiable > Function Copy() As Object >End Interface > >Class Foo > Implements ICopiable > > Function Copy() Implements ICopiable.Copy > ... > End Function >End Class > >Class Bar > Implements ICopiable > > Function Copy() Implements ICopiable.Copy > ... > End Function >End Class > >Sub Test() > Dim al As New ArrayList > al.Add(new Foo) > al.Add(new Bar) > > For Each obj as ICopiable in al > Dim newObj = obj.Copy() > Next >End Sub > >Of course since all the Copy methods you mentioned already implement >IClonable.Clone, then calling Clone is the exact same thing, but if >using a custom ICopiable interface is somehow cleaner or more >understandable, then use that. But don't knock .NET's OOD techniques >when you don't understand how to use them. > >Best regards, > >Sam > > >> >>Sorry, but no...at least not in this manner :-( >> >>I thought the purpose of polymorphism was to eliminate cumbersome if/then >>logic. Besides, there are more classes that implement the Copy() method, >>which means the if/then logic would have to be modifed every time a new >>class was created that implements the Copy() method. This goes against the >>grain of OOD techniques. >> >>I still maintain that late binding is the only solution to 'pure' >>polymorphic behavior such as this. >> >>Daniel Klein >>Cuyahoga Falls, OH
Just to put some closure on this, the piece I was missing was to do: For Each objekt As ICloneable In myArrayList It was the 'As ICloneable' that was missing. Thanks Samuel, I has been educational to say the least. Daniel Klein On Wed, 02 Feb 2005 10:21:51 -0500, Samuel R. Neff [quoted text, click to view] <blinex@newsgroup.nospam> wrote: > >The thing is, ICloneable.Clone() and Copy() are the exact same method. >When you declare > >Function Copy() As Object Implements ICloneable.Clone > >Then you can execute this method via > >obj.Copy() > >or > >DirectCast(obj, ICloneable).Clone() > >And it calls the exact same method. This is called explicit interface >implementation where you're implementing an interface method but >internally using a different method name. This way when the object is >declared as the type that defined it, "Clone" is not accessible, but >"Copy" is. But you can cast it to ICloneable and then "Clone" is >accessible. But no matter what you do, it calls the exact same code, >the contents of the function. > >Sam > > >On Wed, 02 Feb 2005 15:13:18 GMT, Daniel Klein ><danielkleinad@hotmail.com> wrote: > >>IClonaeable.Clone() will never work in this instance due the the 'extra >>work' the Copy() methods have to do. However the ICopiable solution has >>possibilities, I'll let you know. Thanks. >> >>What I was 'knocking' was the if/then logic, not .NET. Apology accepted ;-) >> >>Dan >>
Don't see what you're looking for? Try a search.
|
|
|