【问题标题】:Using generics and a singly linked list (error CS0311)使用泛型和单链表(错误 CS0311)
【发布时间】:2021-09-03 14:30:58
【问题描述】:

我的任务是使用单链表和泛型创建一个集合。为了创建一个单链表,我做了一个特殊的类,没什么不寻常的。

public class Node<T>
{
    public Node(string name)
    {
        Name = name;
    }
    public string Name { get; set; }
    public Node<T> Next { get; set; }
}

然后我制作了一个简短的界面,我在其中编写了所有必要的东西来处理列表。有一些片段要显示:

interface ICustomCollection<T>
{
    void Add(T item);
}

然后我在一个新的集合类中使用了这个接口:

class MyCustomCollection<T> : ICustomCollection<T> where T: Node<T>
{
    T head;
    T tail;
    T current;
    int count = 0;

    public void Add (T item)
    {
        Node<T> node = new(null);

        if (head == null)
        {
            head = (T)node;
        }
        else
        {
            tail.Next = node;
        }
        tail = (T)node;

        count++;
        current = tail;
    }
}

让它成为集合的所有功能。然后我创建了名为 Person 的新类,名称为:

public class Person
{
    string name;
}

所以我需要创建一个类实例来使用集合:

MyCustomCollection<Person> people;

但是现在我有一个编译器错误 CS0311,说没有从“Person”到“Node”的隐式引用转换。我真的不明白该怎么做,我什至尝试做类似的事情:

public static explicit operator Node<Person>(Person person)
{
    return new Node<Person>(person.name){ Next = null, Name = person.name };
}

但它不起作用。你对此有什么想法吗?

【问题讨论】:

  • 我不明白你为什么首先需要MyCustomCollection?你的Node&lt;T&gt; 类已经是你所需要的单链表了。
  • 您的自定义集合要求它由派生自Node&lt;T&gt; 本身的类型参数化。对于集合类来说,这似乎是一个不寻常的要求。为什么要添加 where
  • 您的 Node&lt;T&gt; 类中没有任何通用内容。您有一个字符串,并且您有对下一个节点的引用。您没有任何通用数据成员。你可以简单地拥有一个没有任何泛型的Node

标签: c# visual-studio generics singly-linked-list


【解决方案1】:

您不想要求集合只能包含本身从Node&lt;T&gt; 派生的事物。所以不要把它作为一个要求。只需在内部使用Node&lt;T&gt;

class MyCustomCollection<T> : ICustomCollection<T>
{
    Node<T> head;
    Node<T> tail;
    Node<T> current;
    int count = 0;

此时,您还可以考虑将 Node 类移动到您的集合类中并将其设为私有(如果这样做,您将不再需要参数化 Node 本身,因为它可以使用封闭的 @ 987654326@集合的参数)

您可能还需要使您的Node&lt;T&gt;能够将T 存储为属性。

【讨论】:

  • @NavjotSingh - 因为一旦他们不再混淆集合中包含的项目的节点,节点应该具有T 类型的属性来存储项目。
  • 是的,完全同意
  • @Damien_The_Unbeliever 是的,我认为你是对的,我也想过,但根据任务我需要在方法上使用 T(例如“T Current()”,它显示当前元素,但是使用您的解决方案,我需要编写“Node Current()”。它可以工作,但我考虑过如何留下那个 T,而不是 Note。但我想这不是那么重要,所以谢谢,你证明了我对此有正确的想法。
  • @ГлебБуткевич 你不需要做Node&lt;T&gt; Current(),你仍然可以做T Current()。这个答案的重点是建议您将Node&lt;T&gt; 设为链表结构的_invisible implementation detail`。也就是说,调用代码不需要知道Node&lt;T&gt;,它只是在内部使用。
猜你喜欢
  • 2017-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-22
  • 1970-01-01
  • 2012-06-06
相关资源
最近更新 更多