【问题标题】:How to Implement Dispose In Inheriting Class如何在继承类中实现 Dispose
【发布时间】:2016-07-28 09:57:18
【问题描述】:

我在 .NET-3.5 框架中使用SmtpClient(意味着它没有实现IDisposable),但想将它放在这样的 using 语句中:

using (var client = new DisposableSmtpClient("mail.domain.com", 25)
{ Credentials = new NetworkCredential(), EnableSsl = false })
{
    client.Send(EmailAddress,
                EmailAddress,
                Subject,
                body);
}

所以我创建了以下内容:

class DisposableSmtpClient : SmtpClient, IDisposable
{
    bool disposed; 

    public DisposableSmtpClient(string mailServer, int port) : base(mailServer, port)
    {
        // var client = new SmtpClient(mailServer, port);
    }

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

这可以很好地发送消息,但是在调试时,它会抛出一个StackOverflow 异常(因为this.Dispsoe(); 将永远调用它自己)。

我尝试按照许多其他 SO 问题致电 this.Dispose(true),但这抱怨 No overload for method 'Dispose' takes 1 arguments

base.Dispoe() 也可以工作,当然'SmtpClient' does not conatin a definition for 'Dispose'

最后,我也尝试了签名protected override void Dispose(bool disposing),但我得到Dispose(): no suitable method found to override

有人能指出我正确的方向吗?

【问题讨论】:

  • 你为什么要这样做?你实际上并没有处理(或清理)任何东西,那何必呢?
  • @Maarten 我想我认为调用Send 后仍然存在一些资源,因为SmtpClient 的后续实现实现了IDisposable - 不是这样吗?
  • 也许,但添加一个空的 Dispose 方法不会做任何事情。您实际上需要做一些事情来清理任何东西。
  • 我想当您使用 .Net 3.5 时,最好使用独立的电子邮件组件。像chilkatsoft.com/email-dotnet.asp 这样的东西。为了正确实施 Dispose,您需要释放一些内部 smtpclient 资源,但您无权访问它们。所以如果你只是像空的 Dispose 方法那样实现它,它肯定不能正常工作。

标签: c# .net inheritance dispose


【解决方案1】:

1 - 你不需要处理任何东西,所以你不需要Dispose

去换新的:

var client = new SmtpClient("mail.domain.com", 25)
{ Credentials = new NetworkCredential(), EnableSsl = false };

client.Send(EmailAddress,
            EmailAddress,
            Subject,
            body);

2 - 如果你真的想使用using(我不知道你为什么应该这样做),你必须实现一个空的 dispose (因为你没有任何东西要 dispose开始):

class DisposableSmtpClient : SmtpClient, IDisposable
{
    public DisposableSmtpClient(string mailServer, int port) : base(mailServer, port)
    {
    }

    public void Dispose()
    {
        // anything to do, so don't do anything.
    }
}

IMO,KISS 是您真正应该考虑的原则。

【讨论】:

  • 感谢您的解释。你知道 SmtpClient.Dispose() 在框架的后续版本中实际做了什么吗?
  • 好吧,在以后的版本中,它会处理新的 SmtpClient 实现使用的资源。问题是,在针对 .Net 4 时,您需要查看此代码。或者,您可以在解决方案 2 的 Dispose 实现中使用条件编译。例如将实现包装在 #if Net40 条件中。但这并不简单,如果您不需要同时定位不同的框架版本,我不会打扰。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-15
  • 1970-01-01
  • 2013-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多