【问题标题】:Why I cannot inherit LinkedListNode<T>?为什么我不能继承 LinkedListNode<T>?
【发布时间】:2009-08-25 23:10:40
【问题描述】:

在 .NET 3.5 中,我使用的是 LinkedList 类,但我遇到了以下问题。我希望该列表中的项目知道列表中的上一个和下一个项目。也就是说,我希望items中的方法能够做到this.Next,this.Previous。这可能吗?下面是我想做的一个例子。

Day d1 = new Day();
Day d2 = new Day();
LinkedList<Day> days = new LinkedList<Day>();
days.AddLast(d1);
days.AddLast(d2);

// Here is want I would like to do
d1.Next = ...

谢谢!

【问题讨论】:

    标签: c# .net linked-list


    【解决方案1】:

    首先,LinkedListNodesealed,所以它不能被继承。

    其次,LinkedListNode 确实包含属性PreviousNext,它们引用LinkedList 中的前一个和下一个节点,LinkedListNode 的给定实例来自该节点。

    最后,要正确使用AddLast,您必须执行以下操作:

    Day d1 = new Day();
    Day d2 = new Day();
    LinkedList<Day> days = new LinkedList<Day>();
    LinkedListNode<Day> node1 = days.AddLast(d1);
    LinkedListNode<Day> node2 = days.AddLast(d2);
    
    // now node1.Next refers to node containing d2
    // and node2.Previous referes to node containing d1
    

    【讨论】:

      【解决方案2】:

      你用错了。

      .AddLast(T) 方法返回一个链表节点。这指向您的一天,并具有您正在寻找的 prev 和 next 功能。

      【讨论】:

        【解决方案3】:

        根据MSDN,无法继承LinkedListNode类。

        Michael指出this blog post from Eric Lippert讲为什么框架中的很多类都是密封的

        【讨论】:

        • 我知道...但如果可以的话,它会对我有很大帮助!
        • 我只是假设,因为标题问为什么,我会提供答案!
        • rof;我很纠结这是一个很好的答案还是一个糟糕的答案! “为什么不能继承?” “因为你不能继承它!”。如此准确却如此无用
        • @phsr:从技术上讲,我认为您的消息来源只是证实了这一事实,而不是提供原因。虽然我猜“因为微软不希望你这样做”是一个正当的理由。
        • blogs.msdn.com/ericlippert/archive/2004/01/22/61803.aspx 解释了为什么大多数框架类都是密封的。实际上有充分的理由。
        【解决方案4】:
        Day d1 = new Day();
        Day d2 = new Day();
        LinkedList<Day> days = new LinkedList<Day>();
        // Day's instance doesn't have Next. Its the LinkedListNode that should be used.
        LinkedListNode<Day> d1Node = days.AddLast(d1); 
        days.AddLast(d2);
        

        【讨论】:

        • -1。 LinkedListNode&lt;T&gt;.Next 是只读的。你不能分配给它。
        • @dtb:对不起。我只是从 OP 的问题中获取代码并更正了我认为错误的行。我没有研究是否可以分配给 Next 属性。
        【解决方案5】:

        为什么不直接使用节点开始...

        LinkedListNode<Day> d1 = new LinkedListNode<Day>(new Day());
        LinkedListNode<Day> d2 = new LinkedListNode<Day>(new Day());
        LinkedList<Day> days = new LinkedList<Day>();
        days.AddLast(d1); 
        days.AddLast(d2);
        
        // Now you can read the node directly
        d1.Next...
        
        // If you need to place it somewhere other than at the end (like say you want d2 before d1,
        // but d1 is already in the list) use 'AddBefore' and 'AddAfter' eg:
        days.AddLast(d2);
        days.AddBefore(d2, d1);
        

        【讨论】:

        • 哦,还要提一下,您现在只需通过 d1/d2 的 'Value' 属性访问“Day”
        • -1。 LinkedListNode&lt;T&gt;.Next 是只读的。你不能分配给它。
        • 哦,没看出来,不过你可以通过AddBefore和AddAfter函数来设置
        【解决方案6】:

        我认为让通用T 了解其兄弟姐妹的唯一方法是实现您自己的数据结构。

        public interface ILinkedListNode
        {
            ILinkedListNode Next { get; set; }
            ILinkedListNode Previous { get; set; }
        }
        
        public class LinkedList<T> where T : ILinkedListNode 
        {
            /*.... methods here ...*/
        }
        
        public class Node : ILinkedListNode
        {
            public Node Next { get; set; }
        
            public Node Previous { get; set; }
        
            ILinkedListNode ILinkedListNode.Next
            {
                get { return this.Next; }
                set { this.Next = (Node)value; }
            }
        
            ILinkedListNode ILinkedListNode.Previous
            {
                get { return this.Previous; }
                set { this.Previous = (Node)value; }
            }
        }
        

        【讨论】:

          【解决方案7】:

          LinkedListNode 是一个密封类,因此不能被继承。我们被 IEnumerable 宠坏了,以至于忽略了我们正在使用的实际数据结构。它仍然是一个链表,所以你可以把它当作一个:

          LinkedListNode<Day> node = days.First();
          while (node != null)
          {
              Day day = node.Value;
          
              // do stuff here...
          
              node = node.Next();
          }
          

          【讨论】:

          • -1 这样做您将跳过最后一个节点,因为“days.Last”指的是有效节点。 while 循环应该是 "while (node != null)" 以获取所有节点
          • 感谢指正,但循环中的错误不会改变基本答案:像使用双向链表一样遍历节点来解决问题。
          猜你喜欢
          • 2010-09-28
          • 1970-01-01
          • 2023-03-29
          • 2021-04-16
          • 2023-04-07
          • 2020-01-23
          • 2010-10-20
          • 1970-01-01
          相关资源
          最近更新 更多