我该如何处置一个物体

时间:2013-04-24 14:19:37

标签: c# .net data-structures linked-list idisposable

我正在尝试从链接列表中删除节点。以下是我尝试的代码。

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对象?

3 个答案:

答案 0 :(得分:4)

Dispose(bool)方法中,只有存在下一个节点时才能处置它。在尝试之前检查空引用:

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

答案 1 :(得分:3)

我猜你应该在调用Dispose之前检查Next是否为null。

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

考虑到你提供的代码,我不明白为什么你需要你的节点是一次性的。只有在您使用非托管资源时才需要这样做(在您提供的代码中并非如此)(但也许您可以根据问题对其进行简化)。

答案 2 :(得分: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();
            }                 
        }
    }
}