首先,让我们定义一个节点:
LinkedListNode<int> node = new LinkedListNode<int>(43);
您会注意到属性node.List
,node.Next
和node.Previous
仅为get
。现在让我们将节点添加到LinkedList
:
LinkedList<int> linkedlist = new LinkedList<int>();
linkedlist.AddFirst(node);
此时,属性node.List
将更改为包含对linkedlist
的引用。同样,如果将其他节点添加到LinkedList
,则会更新Next
和Previous
属性以反映链接列表的结构,即使这些属性不公开公共{ {1}}访问者。
这种行为是如何实现的?
我知道如何使用set
来做,但有更好的方法吗?例如,假设我有一个包含多种类型的程序集,而不仅仅是internal
和LinkedList
。通过为节点属性LinkedListNode
,List
和Previous
创建setter,我将这些setter暴露给整个程序集,这是不受欢迎的。
答案 0 :(得分:3)
这种行为是如何实现的?
如果不查看来源,我猜这些属性的setter或支持字段标记为internal
,因此可以从LinkedList<T>
访问,因为它们都位于同一个程序集中。
但有更好的方法吗?
不是真的。让我详细说明一下。还有其他选择。
您可以将LinkedListNode<T>
定义为LinkedList<T>
中定义的内部类。这是一个选择,但它对来电者来说很麻烦。
您可以将LinkedList<T>
和LinkedListNode<T>
刻入自己的程序集中。这显然是用户的负担,并可能迅速降级为维护崩溃。
我认为这两者都不是更好的解决方案。
答案 1 :(得分:1)
我查看了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;
}
}
至于如何区别对待,以及是否要进行讨论,请参阅this question及其答案。
答案 2 :(得分:1)
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>
上没有内部访问者。