【问题标题】:Calling overridden method in generic subclass in C#在 C# 的泛型子类中调用重写的方法
【发布时间】:2011-10-20 17:52:55
【问题描述】:

我自己的通用链表实现有问题。我正在处理的分配说两个子类 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 方法。什么是我看不到的问题?

谢谢你们的帮助,伙计们!

干杯!

【问题讨论】:

  • 你的作业是要求一个通用类还是你的想法?
  • 您为什么认为有问题?如果您能告诉我们一些正在发生的事情以及您预期会发生的事情,这将有助于我们为您提供帮助。
  • 它做错了什么?
  • 您的问题没有显示任何子类...
  • 是的。滚动不足(或滚动太多...)的情况

标签: c# generics overriding


【解决方案1】:

您试图混合两种不同类型的多态性,因为它们具有相反的目标,所以不能很好地混合。

“子类化”又名“临时多态性”的意义在于使类方法的调用者能够在相似的对象上调用相同的方法并拥有发生了不同的事情,因为一些类以特别的方式改变了方法的行为

泛型的重点,也就是“参数多态性”,是为了让类的构造无论数据的类型如何都做完全相同的事情。也就是说,您想要创建一个 AVL 树,并且该 AVL 树的工作方式完全相同,无论它是否填充了整数或字符串。

你试图将这两种多态性相互敲打,但它不起作用。如果您想专门化行为,请使用临时多态性。不要使用参数多态性并期望能够以特别的方式专门化方法行为——参数多态性的全部意义在于不会发生动物的 AVL 树长颈鹿的 AVL 树没有不同的行为,尽管 长颈鹿可能有不同的行为一个动物

【讨论】:

    【解决方案2】:

    它没有按照您的预期执行的原因是您正在创建的 NodeElement 实际上是 NodeElement 类型(与 NodeElementLong 不同)。要完成这项工作,您需要将实际元素类型作为第二个类型参数传入

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

    【讨论】:

    • 嗯,我不确定我是否理解这一点。当我调用 Print 方法时,会调用虚拟方法,但我希望调用子类中适当的重写 Print 方法。没有更简单的解决方案吗?
    • @Expertness:您没有创建子类。您正在创建 NodeElement.
    • 好吧,在这种情况下,解决这个问题的整个方法都是错误的。正如我在上面的描述中所说,我必须有 2 个子类。
    • 您仍然有两个子类.....您的 LinearCollection 将被声明为 LinearCollection 类型。你可以有一个工厂方法,它接受 T 并确定合适的 NodeElement 类型来创建集合。
    【解决方案3】:

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

    在我看来,您似乎还没有掌握泛型的概念。寻找对泛型的良好介绍(搜索引擎 x 会为您提供大量此类介绍)并仔细阅读。

    【讨论】:

    • 那么,有没有简单的方法可以用泛型解决这个问题?
    • 不,不是你的例子。你想达到什么目的?也许如果您提供更具体的示例,我们可以帮助您找到另一种更好的方法。
    • 我试图实现 Print 方法会根据实例是 long 类型还是 string 类型进行不同的打印。这是一般的想法,在泛型的帮助下,我认为它可能会起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多