Home > Microsoft .Net Development Tips > Visual Basic and Visual Basic .NET > Polymorphism can lead to head scratching in VB.NET
Win Development Tips:
EMAIL THIS
 TIPS & NEWSLETTERS TOPICS 

VISUAL BASIC AND VISUAL BASIC .NET

Polymorphism can lead to head scratching in VB.NET


Eric Mutta
10.01.2003
Rating: -3.32- (out of 5)


Digg This!    StumbleUpon Toolbar StumbleUpon    Bookmark with Delicious Del.icio.us   


This tip was submitted to the VS.NET Info Center by member Rick Spiewak. Please let other users know how useful it is by rating it below. Do you have a tip or code of your own you'd like to share? Submit it here.


Many VB developers have probably heard the statement: "VB6 does support full object oriented programming, so it's not a 'real' language." Now with VB7 (VB.NET), OOP is here in all its glory. Well, it's here, but it sure isn't all glory -- at least not when it comes to polymorphism. In this tip, I will show a rather nasty pitfall that can happen when you use polymorphism in VB.NET.

The code below is very simple, very naive. However, it could take several hours of head scratching to figure out what's wrong. Before you paste it into a new console application project, try and figure out why the stack overflow occurs without using the debugger to trace through the execution path.

Module MyModule
    Class Parent
        Public Overridable Sub p1()
            Console.Write("Parent.p1")
        End Sub

        Public Sub p2()
            'blah blah
            p1()
            'blah blah
        End Sub
    End Class

    Class Child
        Inherits Parent

        Public Overrides Sub p1()
            Console.Write("Child.p1")
            MyBase.p2()
        End Sub
    End Class

    Sub Main()

        Dim p As Parent
        Dim c As Child

        p = New Parent()
        p.p1() 'OK
        p.p2() 'OK

        p = New Child()
        p.p1() 'stack overflow
        p.p2() 'stack overflow

        c = New Child()
        c.p1() 'stack overflow
        c.p2() 'stack overflow

    End Sub
End Module

This is not something I discovered by accident. I actually designed it by making use of my understanding of polymorphism. The problem is, it can happen without you knowing in your everyday coding work, whether you like it or not.

So why does the stack oveflow occur?

*Parent.p2() calls Parent.p1()
*Parent.p1() is polymorphic because it can be overriden
*Child.p1() overrides Parent.p1() so any calls to Parent.p1() will actually 
call Child.p1() if you have an instance of class Child. 
*Child.p1() calls MyBase.p2()
*MyBase.p2() is actually Parent.p2()

Now if you are still with me, the pitfall comes when you have an instance of class Child and call procedures p1 and p2. Calling p1 produces the following execution flow:

Child.p1 -> Parent.p2 -> Child.p1 -> Parent.p2 -> Child.p1 -> etc.

and the cycle repeats until we have no stack space left. Calling p2 produces the following execution flow:

Child.p2 -> Child.p1 -> Parent.p2 -> Child.p1 -> Parent.p2 -> Child.p1 -> etc.

If you are lost (which is perfectly human given the complexity of the pitfall), then the best way to understand it is to step through the code when the following lines in Sub Main execute:

        p = New Parent()
        p.p1() 'OK
        p.p2() 'OK

        p = New Child()
        p.p1() 'stack overflow
        p.p2() 'stack overflow

        c = New Child()
        c.p1() 'stack overflow
        c.p2() 'stack overflow

Some things to note:

  • The writer of Parent.p2 would probably expect his or her p1() call to go to Parent.p1(), which it does, if we have an instance of Parent. The oversight comes in either completely forgetting that the call is polymorphic, or assuming that p1() in child classes will work like the one in Parent.

  • The writer of Child.p1() would have no idea that Parent.p2() calls Parent.p1(). As a result, he or she would have no clue that calling MyBase.p2() would lead to a polymorphic call back into Child.p1() and start a cycle (this is what causes the stack overflow).

  • The overflows would not occur if polymorphism wasn't used -- i.e. Parent.p1() was not overridable.

  • The problem is further compounded by the fact that the polymorphic calls don't stand out and look different to non-polymorphic calls, which makes it harder to realise that the problem is caused by a polymorphic call.

    Now for the tip:

  • If you are designing a class, use polymorphism only if absolutely necessary. Also, don't depend on the behavior of your polymorphic methods, because that behaviour WILL change, when child classes override your class, and lead to things like this pitfall.

  • If you are inheriting from a class, override only the methods that you need to override.

  • If you have code for the parent class, try and find a method that is (a) called from your child class, (b) defined in the parent class you are inheriting from, and (c) calls a method that you have overriden. If you can find such a method, then this pitfall WILL occur sooner or later in your code.

    The full glory of OOP is now in VB.NET, but so are the nightmares. So be careful, and happy coding!

    Rate this Tip
    To rate tips, you must be a member of SearchWinDevelopment.com.
    Register now to start rating these tips. Log in if you are already a member.




    Digg This!    StumbleUpon Toolbar StumbleUpon    Bookmark with Delicious Del.icio.us   



    RELATED CONTENT
    Visual Basic and Visual Basic .NET
    Compose XML more quickly using Visual Basic 9
    Virtualization keeps Legacy Apps alive
    VB 9 Anonymous Types help create flexible objects
    Visual Studio Team System Add-ins: Conchango Scrum for Team System and Scrum Dashboard
    Book Excerpt: Sams Teach Yourself Visual Basic 2008 in 24 Hours -- Complete Starter Kit
    Check out CodePlex for a ton of interesting .NET projects
    Book excerpt: Murach's VB 2008
    Book excerpt: Printing in Visual Basic 2005
    Visual Basic 2008 and closures
    WinForms development using SQL Server 2005 and Visual Basic 2005

    RELATED RESOURCES
    2020software.com, trial software downloads for accounting software, ERP software, CRM software and business software systems
    Search Bitpipe.com for the latest white papers and business webcasts
    Whatis.com, the online computer dictionary

    DISCLAIMER: Our Tips Exchange is a forum for you to share technical advice and expertise with your peers and to learn from other enterprise IT professionals. TechTarget provides the infrastructure to facilitate this sharing of information. However, we cannot guarantee the accuracy or validity of the material submitted. You agree that your use of the Ask The Expert services and your reliance on any questions, answers, information or other materials received through this Web site is at your own risk.



  • Database Programming Solutions - .NET XML, Visual Studio LINQ, ORM .NET
    About Us  |  Contact Us  |  For Advertisers  |  For Business Partners  |  Site Index  |  RSS
    SEARCH 
    TechTarget provides technology professionals with the information they need to perform their jobs - from developing strategy, to making cost-effective purchase decisions and managing their organizations' technology projects - with its network of technology-specific websites, events and online magazines.

    TechTarget Corporate Web Site  |  Media Kits  |  Site Map




    All Rights Reserved, Copyright 2000 - 2009, TechTarget | Read our Privacy Policy
      TechTarget - The IT Media ROI Experts