代码之家  ›  专栏  ›  技术社区  ›  esac

如何处理通过下一个属性遍历的对象?

  •  2
  • esac  · 技术社区  · 16 年前

    我有一个对象,它使用一些底层本机资源,并有一个指向下一个实例的指针,我遍历该实例类似于:

    MyObject begin = null;
    
    try
    {
        begin = GetFirst();
    
        while (begin != null)
        {
            MyObject next = begin.Next();
            // do something with begin
            begin.Dispose();
            begin = next;
        }
    }
    finally
    {    
        if (begin != null)
        {
            begin.Dispose();
        }
    }
    

    你知道我怎样才能消除这个错误而不抑制它吗?

    3 回复  |  直到 16 年前
        1
  •  4
  •   Dan Tao    16 年前

    在我看来,你的最后一段代码是没有必要的。如果 begin != null ,然后你的 while 循环应该继续,不是吗?

    更新 begin 在引发异常时释放。试试这个:

    MyObject begin = GetFirst();
    
    while (begin != null)
    {
        MyObject next;
        using (begin)
        {
            next = begin.Next();
            // do something with begin
        }
    
        begin = next;
    }
    

    请注意,在上面的建议中,实际上仍然可能出现这样的情况:您最终得到一个未经处理的对象:最后一个赋值给 next using 阻止。你最初的问题没有涉及到这个场景,所以我在上面的建议中没有提到。不过,如果这是一个潜在问题的话,这是需要考虑的。

        2
  •  0
  •   kbrimington    16 年前

    代码分析似乎认为在测试过程中可能发生异常 Dispose() begin

    请注意,如果您计划将调用包装到@Dan,我只希望使用这种方法 begin.Dispose() 额外的错误捕获和处理。在我看来,丹的解决方案更为优雅。

    下面是一个try finally方法,它消除了警告:

    MyObject begin = GetFirst();
    MyObject next = null;
    
    while (begin != null)
    {
        try
        {
            next = begin.Next();
            // do something with begin
        }
        finally
        {
            begin.Dispose();
            begin = next;
        }
    }
    
        3
  •  0
  •   Ian Johnson    16 年前

    在最初调用dispose的代码中:

    GetFirst().Dispose();
    

    那么dispose方法的唯一职责就是处理当前项及其子项:

    public void Dispose()
    {
        if (Next() != null)
        {
            Next().Dispose();
        }
    }
    

    dispose pattern