简体   繁体   中英

Calling overridden method in generic subclass in C#

I'm having problems with my own implementation of generic linked list. Assignment that I'm working on says that two subclasses NodeElementLong and NodeElementString must descend from base class NodeElement. In NodeElement there should be a virtual method Print which descendant classes override and implement in their own way. When I call Print method on element of type long, for instance, the Print method within NodeElementLong subclass must be called.

Here's the code:

class LinearCollection<T>
{
    NodeElement<T> head = null;

    public bool Add(T element)
    {
        if (head == null)
        {
            head = new NodeElement<T>(element);
        }
        else
        {
            NodeElement<T> current = head;
            while (current.nextNode != null)
            {
                current = current.nextNode;
            }
            current.nextNode = new NodeElement<T>(element);
        }
        return true;
    }

    public NodeElement<T> Get() 
    {
        NodeElement<T> head1 = head;
        head = head.nextNode;
        return head1;
    }

    public void Print()
    {
        for (NodeElement<T> element = head; element != null; element = element.nextNode)
        {
            element.Print();
        }
    }
}

class NodeElement<T>
{
    public T element;
    public NodeElement<T> nextNode = null;

    public NodeElement() { }

    public NodeElement(T element)
    {
        this.element = element;
    }

    public virtual void Print()
    {
        Console.WriteLine(element);
    }
}

class NodeElementLong : NodeElement<long>
{
    public override void Print()
    {
        Console.WriteLine("This is print long: " + element);
    }
}

class NodeElementString : NodeElement<string>
{
    public override void Print()
    {
        Console.WriteLine("This is print string: " + element);
    }
}

I'm just starting with C# programming and I'm not that familiar with generics, but my assignment insists on using them. When I call Print method, the virtual method is called, but I want the appropriate overridden Print method within subclass to be called. What is wrong that is invisible to me?

Thanks for your help, guys!

Cheers!

You're trying to mix two different kinds of polymorphism that do not mix well because they have opposing aims.

The point of "subclassing" aka "ad-hoc polymorphism" is to enable callers of class methods to call the same methods on similar objects and have different things happen because some of the classes changed the method behaviours in an ad-hoc manner .

The point of generics, aka "parametric polymorphism" is to enable construction of classes that do exactly the same thing regardless of the type of the data . That is, you want to make an AVL tree, and that AVL tree works exactly the same regardless of whether it is stuffed full of ints or strings.

You're trying to hammer those two kinds of polymorphism into each other, and it's not working. If you want to specialize behaviour, use ad-hoc polymorphism. Don't use parametric polymorphism and expect to be able to specialize method behaviours in an ad-hoc manner -- the whole point of parametric polymorphism is that that does not happen. An AVL tree of Animals does not have different behaviour than an AVL tree of Giraffes , regardless of the fact that a Giraffe might have different behaviour than an Animal .

The reason it's not doing what you expect is that the NodeElement you're creating is actually of type NodeElement<long> (which is not the same as NodeElementLong). To make this work you'll need to pass in the actual element type as a second type parameter

class LinearCollection<T, NodeType> where NodeType : NodeElement<T>, new()
{
    public bool Add(T element)
    {
        if (head == null)
        {
            head = new NodeType();
            head.Value = element;
        }
        ...
    }
}

The whole thing about generic types is that you do not need specific implementations like this.

It seems to me like you did not grasp the concept of generics yet. Look for a good introduction to generics (search engine x will give you tons of those) and work through it carefully.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM