LinkedList和LinkedListNode< T>在c#中实现

本文关键字:实现 LinkedList LinkedListNode | 更新日期: 2023-09-27 18:18:01

首先,让我们定义一个节点:

LinkedListNode<int> node = new LinkedListNode<int>(43);

您会注意到属性node.List, node.Nextnode.Previous都是get only。现在让我们将节点添加到LinkedList:

LinkedList<int> linkedlist = new LinkedList<int>();
linkedlist.AddFirst(node);

此时,属性node.List将被更改为包含对linkedlist的引用。同样,如果其他节点被添加到LinkedList, NextPrevious属性将被更新以反映链表的结构,即使这些属性没有公开公共set访问器。

这个行为是如何实现的?

我知道如何使用internal,但是有更好的方法吗?例如,假设我有一个包含许多类型的程序集,而不仅仅是LinkedListLinkedListNode。通过为节点属性List, PreviousNext设置setter,我将这些setter暴露给整个程序集,这是不希望的。

LinkedList<T>和LinkedListNode< T>在c#中实现

这个行为是如何实现的?

在不查看源代码的情况下,我猜这些属性的setter或backing字段标记为internal,因此可以从LinkedList<T>访问,因为它们都位于同一个程序集中。

但是有更好的方法吗?

没有。让我详细说明一下。还有其他选择

  1. 您可以使LinkedListNode<T>成为在LinkedList<T>中定义的内部类。

  2. 您可以将LinkedList<T>LinkedListNode<T>雕刻成自己的汇编。这显然是用户的负担,并可能很快降级为维护崩溃。

我认为这两种方法都不是更好的解决方案。

我检查了ILSpy,只读属性是由internal字段支持的。

internal LinkedListNode<T> next;
public LinkedListNode<T> Next {
    get {
        if (this.next != null && this.next != this.list.head) {
            return this.next;
        }
        return null;
    }
}

至于如何做不同的,以及你是否想要的讨论,看看这个问题和它的答案。

Jason是正确的。我看了一下源代码,LinkedListNode<T>有内部支持字段。

一种方法是使用嵌套类。我不知道这是否是一种"更好"的方式,但它确实避免了内部setter/字段。我省略了一些实现,所以您可以看到结构的轮廓:
public class Node<T>
{
  private List list;
  private Node<T> prev, next;
  public List List { get { return list; } }
  // other accessors.
  public abstract class List
  {
    Node<T> head;
    internal List() { }
    public AddFirst(Node<T> node)
    {
        // node adding logic.
        node.list = this;       
    }
    // implementation elided for brevity
  }
}
public class MyLinkedList<T> : Node<T>.List { }

现在您可以声明MyLinkedList并向其添加节点,但是Node<T>上没有内部访问器