2013-04-24 172 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(); 
      }     
     } 
    } 
}