2013-04-24 81 views
2

我想从链接列表中删除节点。以下是我尝试过的代码。如何处理对象

public class Node : IDisposable 
{ 
    public int Value { get; set; } 
    public Node Next { get; set; } 

    public Node(int value) 
    { 
     this.Value = value; 
    } 

    public void Dispose() 
    { 
     Dispose(true); 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      Next.Dispose(); 
     } 
    } 
} 

public class LinkedList 
{ 
    Node head; 
    public void CreateList() 
    { 
     Node node1 = new Node(1); 
     Node node2 = new Node(2); 
     Node node3 = new Node(3); 

     head = node1; 
     node1.Next = node2; 
     node2.Next = node3; 
    } 

    public void DeleteLastItem() 
    { 
      Node prevNode = head; 
      Node nextNode = head; 

      while (nextNode.Next != null) 
      { 
       prevNode = nextNode; 
       nextNode = nextNode.Next; 
      } 
      prevNode.Next = null; 
      nextNode.Dispose(); 
    } 
} 

我想处置nextNode(这是什么,但最后一个节点。它不会是链表的一部分)。

当我尝试上面的代码中,我得到以下异常:

未处理的异常:System.NullReferenceException:对象不设置到对象的实例。

我该怎么办?我如何处置一个Node对象?

+6

什么让你觉得一个'Node'需要处置的?另外,为什么要编写自己的链接列表而不是使用[内置的](http://msdn.microsoft.com/zh-cn/library/he2s3bh7.aspx)? – Jon 2013-04-24 14:21:28

+3

@Jon可以用于学习目的。 – OmniOwl 2013-04-24 14:21:54

+1

我知道GC会自动配置节点。此外,LinkedList类存在.NET。我这样做只是为了我的兴趣去了解内部的事情。 – SKJ 2013-04-24 14:23:34

回答

4

在您的Dispose(bool)方法中,如果有下一个节点,则只能处理下一个节点。在尝试之前检查空引用:

protected virtual void Dispose(bool disposing) { 
    if (disposing) { 
    if (Next != null) { 
     Next.Dispose(); 
    } 
    } 
} 
3

我想你应该在调用Dispose之前简单地检查Next是否为空。

当在任何节点上调用Dispose方法时,您都会手动调用下一个,以便您可以到达最后一个节点,Next属性将为null,因此您会得到此异常。

考虑到你提供的代码,我不明白为什么你需要你的节点是一次性的。只有在您使用非托管资源时才需要使用非代码资源(但您可能已简化了该问题)。

1

在你的Dispose逻辑,检查NULL:

public class Node : IDisposable 
{ 
    public int Value { get; set; } 
    public Node Next { get; set; } 

    public Node(int value) 
    { 
     this.Value = value; 
    } 

    public void Dispose() 
    { 
     Dispose(true); 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      if (Next != null) // <-- new code here 
      { 
       Next.Dispose(); 
      }     
     } 
    } 
}