Est*_*ban 3 .net c# garbage-collection dispose idisposable
我已经看过像这样的问题,甚至我发现了很多,其中任何一个都为我提出了这个问题.
我们假设我有这个代码:
public class SuperObject : IDisposable
{
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing) { }
}
Run Code Online (Sandbox Code Playgroud)
protected virtual void Dispose(bool)
上SuperObject
?因为那里真的没有什么可以处理的.public interface ICustom : IDisposable { }
Run Code Online (Sandbox Code Playgroud)
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();
}
}
Run Code Online (Sandbox Code Playgroud)
public class Foo
{
public Foo()
{
using (var c = new Custom())
{
//do magic with c
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在如果我想要/需要/尝试Custom
在System.Web.Mvc.Controller
已经实现并已实现IDisposable 的类上使用会发生什么?
public class Moo : Controller
{
Custom c;
public Moo()
{
c = new Custom();
}
// Use c throughout this class
}
Run Code Online (Sandbox Code Playgroud)
如何妥善处置c
的Moo
?
通常的方法是应用标准的IDispoable实现 - 但是,如果您的类或从中派生的类将使用非托管资源,这实际上是必要的 - 这种情况实际上非常罕见(当这种情况适用时,最好包装其自己的类中的非托管资源,具有完整的标准IDisposable实现).
因此,假设您没有处理非托管资源(原始文件句柄,全局分配的内存等),并且只处理一次性成员(即具有托管资源并实现IDisposable),那么您可以安全地获得一种方式,使其具有最小的实现性. IDispose - 即:
只需要一个void Dispose()方法.在那个方法中,只需要在dispoable成员上调用dispose,然后在基类上Dispose,如果它是一次性的.如果你有一个类层次,那么可以使这个Dispose虚拟化.不需要Dispose(bool)方法.也没有必要检查对象是否被处置 - 因为你所做的就是在其他对象上调用dipsose,而那些实现将进行检查.
如果您不喜欢mimimal appraoch,那么应用标准的完整实施(但并非绝对必要).即要么做一个标准的实施,因为你是一个遵循推荐方法的坚持者或做一个简单的最小(但正确)的实现 - 但不要在两者之间做一些事情(即不标准,不简单或不正确)!
有关更多详细信息,请参阅此问题:仅限托管资源的最小IDispose implimenation
所以在你的情况下,以下是mimimal implimentation:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,如果Super对象没有任何可支配资源,那么实现IDisposable并使用Dispose方法就没有意义.如果海关只有一次性对象是SuperObject,那么同样适用于那里,并且同样的逻辑通过Moo.最后,如果上述所有情况都适用,并且周围没有其他一次性物品,那么您真正需要的是:
public class Moo : Controller {
Custom c;
public Moo() {
c = new Custom();
}
public Dispose() {
base.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)