【问题标题】:How can I dispose an object我怎样才能处置一个对象
【发布时间】:2013-04-24 14:19:36
【问题描述】:

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

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

【问题讨论】:

  • 是什么让您认为需要处理 Node?另外,为什么要编写自己的链表而不是使用the built-in one
  • @Jon 可能用于学习目的。
  • 我知道GC会自动处理节点。此外,存在 .NET 的 LinkedList 类。我这样做只是因为我有兴趣了解内部事物。
  • IDisposable 接口/模式适用于托管类型使用需要释放的本机资源时。
  • @Bunyip 不,GC 将不会自动处理节点。整个IDisposable 模式的存在是为了允许处理 GC 无法正确清理的资源。如果您没有此类非托管资源,则没有理由实施IDisposable

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


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

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

    考虑到您提供的代码,我不明白您为什么需要您的节点是一次性的。仅当您使用非托管资源时才有必要,而您提供的代码中并非如此(但也许您为问题简化了它)。

    【讨论】:

      【解决方案3】:

      在您的 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();
                  }                 
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2016-04-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-24
        • 2017-06-02
        • 2016-08-28
        • 1970-01-01
        相关资源
        最近更新 更多