简体   繁体   English

LinkedList之间如何交互 <T> 和LinkedListNode <T> 用C#实现?

[英]How is the interaction between LinkedList<T> and LinkedListNode<T> implemented in C#?

First, let's define a node: 首先,让我们定义一个节点:

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

You'll notice that the properties node.List , node.Next and node.Previous are all get only. 您会注意到,属性node.Listnode.Nextnode.Previous都只能get Now let's add the node to a LinkedList : 现在,将节点添加到LinkedList

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

At this point, the property node.List will have change to contain a reference to linkedlist . 此时,属性node.List将进行更改以包含对linkedlist的引用。 Similarly, if other nodes are added to the LinkedList , the Next and Previous properties will be updated to reflect the structure of the linked list, even though these properties do not expose a public set accessor. 同样,如果将其他节点添加到LinkedList ,则NextPrevious属性将被更新以反映链接列表的结构,即使这些属性未公开公共set访问器也是如此。

How is this behavior implemented? 如何实施此行为?

I know how to do it using internal , but is there a better way? 我知道如何使用internal ,但是有更好的方法吗? For example, suppose I have a single assembly that contains many types, not just LinkedList and LinkedListNode . 例如,假设我有一个包含多种类型的程序集,而不仅仅是LinkedListLinkedListNode By making the setters for the node properties List , Previous and Next , I am exposing these setters to the whole assembly, which is undesired. 通过为节点属性ListPreviousNext setter,我将这些setter暴露给整个程序集,这是不希望的。

How is this behavior implemented? 如何实施此行为?

Without looking at the source, I would guess the setters or backing fields for those properties are marked internal and therefore accessible from LinkedList<T> since they both sit in the same assembly. 如果不查看源代码,我可能会猜想这些属性的设置程序或后备字段标记为internal ,因此可以从LinkedList<T>访问,因为它们都位于同一程序集中。

but is there a better way? 但是有更好的方法吗?

Not really. 并不是的。 Let me elaborate. 让我详细说明。 There are other options. 还有其他选择。

  1. You could make LinkedListNode<T> an inner class defined in LinkedList<T> . 你可以使LinkedListNode<T>中定义的内部类LinkedList<T> That's an option, but it's burdensome on callers. 这是一个选择,但对呼叫者来说是沉重的负担。

  2. You could carve LinkedList<T> and LinkedListNode<T> into their own assembly. 您可以将LinkedList<T>LinkedListNode<T>雕刻到它们自己的程序集中。 That's obviously a burden on users and could quickly degrade into a maintenance debacle. 这显然给用户带来负担,并且可能很快退化为维护崩溃。

I characterize both of these as not being better solutions. 我认为这两种方法都不是更好的解决方案。

I checked with ILSpy, the read-only properties are backed by internal fields. 我检查了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;
    }
}

As for how to do it differently, and a discussion of whether you'd want to, see this question and its answers. 至于如何做不同的事情,以及是否愿意的讨论,请参阅此问题及其答案。

Jason is correct. 杰森是正确的。 I had a look at the source and LinkedListNode<T> has internal backing fields. 我查看了源代码, LinkedListNode<T>具有内部支持字段。

One way to do this is with nested classes. 一种方法是使用嵌套类。 I don't know if this qualifies as a "better" way, but it does avoid internal setters/fields. 我不知道这是否符合“更好”的方式,但是它确实避免了内部设置器/字段。 I've left out some of the implementation, so you can see an outline of the structure: 我省略了一些实现,因此您可以看到结构的轮廓:

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 { }

Now you can declare a MyLinkedList and add nodes to it, but there are no internal accessors on Node<T> . 现在,您可以声明MyLinkedList并向其中添加节点,但是Node<T>上没有内部访问器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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