在C#中调用泛型子类中的重写方法

时间:2011-10-20 17:52:55

标签: c# generics override

我遇到了自己的通用链表实现问题。我正在研究的分配说两个子类NodeElementLong和NodeElementString必须从基类NodeElement下降。在NodeElement中应该有一个虚拟方法Print 后代类以自己的方式覆盖和实现。例如,当我在long类型的元素上调用Print方法时,必须调用NodeElementLong子类中的Print方法。

以下是代码:

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);
    }
}

我刚刚开始使用C#编程,我对泛型并不熟悉,但我的任务仍然坚持使用它们。当我调用Print方法时,会调用虚方法,但我希望调用子类中适当的重写Print方法。我看不出有什么问题?

感谢您的帮助,伙计们!

干杯!

3 个答案:

答案 0 :(得分:13)

你试图将两种不同的多态性混合起来,因为它们有相反的目的,因此不能很好地混合。

“子类化”又称“ad-hoc多态”的观点是使类方法的调用者能够在类似对象上调用相同的方法 并拥有发生了不同的事情因为某些类以临时方式改变了方法行为

泛型,即“参数多态”,即使无论数据的类型如何,都能构建完全相同的类。也就是说,你想要制作一个AVL树,并且AVL树的工作方式完全相同,无论它是否充满了整数或字符串。

你试图将这两种多态性相互冲突,但它无法正常工作。如果要专门化行为,请使用ad-hoc多态。不要使用参数多态并期望能够以特别的方式专门化方法行为 - 参数多态的整个要点是不会发生。动物的 AVL树与长颈鹿的 AVL树没有不同的行为,无论 Giraffe 的行为可能与一个动物

答案 1 :(得分:3)

它没有按照您的期望进行操作的原因是您创建的NodeElement实际上是NodeElement类型&lt; long&gt; (与NodeElementLong不同)。要使这项工作,您需要将实际的元素类型作为第二个类型参数传递

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

答案 2 :(得分:1)

关于泛型类型的全部内容是您不需要像这样的特定实现。

在我看来,你还没有掌握仿制药的概念。寻找对泛型的一个很好的介绍(搜索引擎x会给你很多)并仔细研究它。