2016-07-28 120 views
0

我在.NET的框架3.5使用SmtpClient(这意味着它没有实现IDisposable),但希望把它放在一个using语句,像这样:如何实现Dispose在继承类

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();只会调用自己永远)。

我试着拨打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

有没有人能够指出我在这个正确的方向?

+1

你为什么要这么做?你实际上并没有处理(或清除)任何东西,所以为什么要麻烦? – Maarten

+0

@Maarten我猜我认为有些资源在调用'Send'后仍然存在,因为'SmtpClient'的后续实现实现了'IDisposable' - 是不是这种情况? – Bassie

+1

也许但添加一个空的Dispose方法将不会执行任何操作。你需要真正做些什么来清理任何东西。 – Maarten

回答

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(因为你不没有任何东西需要处理):

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是一个你应该考虑的原则。

+0

谢谢你的解释。你知道'SmtpClient.Dispose()'在框架的后续版本中实际做了什么? – Bassie

+1

那么,在更高版本中,它会处理新的SmtpClient实现所使用的资源。问题是,您需要在定位.Net 4时查看此代码。或者,您可以在解决方案2中的Dispose实现中使用条件编译。将实现包装在#if Net40条件中。但这并不简单,如果你不需要同时定位不同的框架版本,我就不会烦恼。 –