了解一次性物品

2023-12-24

我查过类似这样的问题,即使我发现了很多问题,但其中任何一个都为我解决了这个问题。

假设我有这段代码:

public class SuperObject : IDisposable
{
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing) { }
}
  • 我需要吗protected virtual void Dispose(bool) on SuperObject?因为那里确实没有什么可以处理的。
public interface ICustom : IDisposable { }
public class Custom : ICustom
{
    public SuperObject Super { get; protected set; }

    public Custom()
    {
        Super = new SuperObject();
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    public virtual void Dispose(bool disposing)
    {
        if (!disposing) return;

        if (Super != null)
            Super.Dispose();
    }
}
public class Foo
{
    public Foo()
    {
        using (var c = new Custom())
        {
            //do magic with c
        }
    }
}

现在如果我想要/需要/尝试使用会发生什么Custom在像这样的课程上System.Web.Mvc.Controller哪个已经实现并且已经实现了 IDisposable?

public class Moo : Controller
{
    Custom c;

    public Moo()
    {
        c = new Custom();
    }

    // Use c throughout this class        
}

如何正确处置c in Moo?


正常的方法是应用标准 IDisposable 实现 https://learn.microsoft.com/en-us/dotnet/api/system.idisposable?view=net-5.0- 然而,只有当您的类或从它派生的某些类将使用非托管资源时,这实际上才是必要的 -这种情况实际上非常罕见(当这种情况确实适用时,最好将非托管资源包装在其自己的具有完整标准 IDisposable 实现的类中)。

因此,假设您不处理非托管资源(原始文件句柄、全局分配的内存等),而只处理一次性成员(即具有托管资源并实现 IDisposable),那么您可以安全地找到一种最小实现的方法IDispose - 即:

只有一个 void Dispose() 方法。在该方法中,只需对可一次性成员调用 dispose,然后对基类(如果是一次性成员)调用 Dispose。如果你有一个类层次结构,可以将这个 Dispose 设为虚拟。不需要 Dispose(bool) 方法。也不需要检查对象是否已释放 - 因为您所做的只是在其他对象上调用 dipsose,并且这些实现将执行该检查。

如果您不喜欢最小的方法,则应用标准的完整实现(但这并不是绝对必要的)。即要么做一个标准的实现,因为你坚持遵循推荐的方法,要么做一个简单的最小(但正确)的实现 - 但不要做介于两者之间的事情(即不标准,不简单或不正确)!

请参阅此问题了解更多详细信息:仅针对托管资源的最小 Dispose 实现 https://stackoverflow.com/questions/18970742/minimal-idispose-implimenation-for-managed-resources-only

因此,在您的情况下,以下是最小的实现:

public class SuperObject : IDisposable {
    public void Dispose() {
        // Dispose code...just call dispose on dispoable members.
        // If there are none then no need to implement IDisposable!
    }
}

public interface ICustom : IDisposable { }
public class Custom : ICustom {
    public SuperObject Super { get; protected set; }

    public Custom() {
        Super = new SuperObject();
    }

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

public class Moo : Controller {
    Custom c;

    public Moo() {
        c = new Custom();
    }

    public Dispose() {
        if (c!=null)
            c.Dispose()
        base.Dispose();       
    }
}

请注意,如果 Super 对象没有任何可处置资源,则实现 IDisposable 并拥有 Dispose 方法是没有意义的。如果海关唯一的一次性对象是 SuperObject,那么同样的情况也适用,并且同样的逻辑再次适用于 Moo。最后,如果上述所有内容都适用并且周围没有其他一次性物品,那么您真正需要的是:

  public class Moo : Controller {
        Custom c;
    
        public Moo() {
            c = new Custom();
        }
    
        public Dispose() {
           base.Dispose();       
        }
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

了解一次性物品 的相关文章