2015-07-20 56 views
5

我在C#.NET 4.0中處理一個巨大的項目。有一個繼承自System.Net.Sockets.SocketAsyncEventArgs類的自定義類。類似以下內容:如何在繼承自SocketAsyncEventArgs的類中實現IDisposable接口

public class SocketTaskArgs : SocketAsyncEventArgs 
{ 
    public SocketTaskArgs() 
    { 
     Completed += someEventhHandler; 
    } 

    public void CleanUp() 
    { 
     Completed -= someEventhHandler; 
    } 

    /* 
     There is a lot of code here that is unimportant at the moment. 
    */ 
} 

所以,我想將CleanUp()方法的內容移到Dispose(bool)方法。首先,我檢查了基類 - SocketAsyncEventArgs的源代碼(使用轉到定義,以便我看到元數據作爲源)。我發現,這個類實現了IDisposable接口。很好,我只需要重寫Dispose(bool)方法,不是嗎? (有關更多詳細信息,請參見IDisposable Interface on MSDN,「IDisposable」和「繼承層次」部分)。對我來說沒有什麼新的......不幸的是,讓SocketAsyncEventArgs類實現如下:

public class SocketAsyncEventArgs : EventArgs, IDisposable 
{ 
    public void Dispose(); 

    //some other stuff here 
} 

這意味着,有沒有辦法如何覆蓋的Dispose(布爾)方法,因爲它是作爲私人代替實施保護 ... 這是什麼原因?

接下來,我讀了關於在MSDN上的SocketAsyncEventArgs.Dispose()方法。有趣的是,它包含以下內容:

給繼承

處置可以通過其他 對象可以多次調用。當覆蓋配置(布爾型)時,請注意不要參考 之前已在之前處理過的對象中處理過的對象 處置。有關如何實施Dispose(布爾型), 的更多信息,請參閱實施處置方法。

等等......什麼?

當重寫的Dispose(布爾) ...

我怎麼重寫的Dispose(布爾)?

什麼是落實在這種情況下IDisposable接口是推薦的方式?

+1

它不是私有的,它根本沒有實現(請參閱http://referencesource.microsoft.com/System/net/System/Net/Sockets/Socket.cs.html#8877)。它確實使用了終結器,但看起來並沒有在推薦模式中實現。 –

+0

它看起來像'Dispose'是公開的,而不是'虛擬'。 –

+0

你不應該從該類繼承。在現有大型項目中,您可能無法輕鬆改變這一點。 – usr

回答

3

似乎沒有要任何東西從你的子類實現IDisposable阻止你,拿這個例子:

public class DisposableParent : IDisposable 
{ 
    public void Dispose() 
    { 
     Console.WriteLine("The parent was disposed."); 
    } 
} 

public class DisposableChild : DisposableParent, IDisposable 
{ 
    public new void Dispose() 
    { 
     base.Dispose(); 
     Console.WriteLine("The child was disposed."); 
    } 
} 

public class Program 
{ 
    public static void Main() 
    { 
     using (DisposableChild c = new DisposableChild()) { } 
     Console.ReadKey(true); 
    } 
} 

提供了以下的輸出:

家長被佈置。

孩子被處置。

編譯器警告有關隱藏父類的Dispose的孩子,所以使用new運營商擺脫這一警告的,只是請確保調用從子類的基類Dispose(和實現它的正確的方法)。

的孩子會成爲什麼樣的配置:

public class DisposableChild : DisposableParent, IDisposable 
{ 
    private bool _disposed = false; 

    public new void Dispose() 
    { 
     Dispose(true); 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      if (!_disposed) 
      { 
       base.Dispose(); 
       Console.WriteLine("The child was disposed."); 
       _disposed = true; 
      } 
     } 
    } 
} 

是的,如果你做這樣的事情仍然有效:

using (DisposableParent p = new DisposableChild()) 
{ 

} 

但是像這樣可以打破它:

public class Program 
{ 
    public static void Main() 
    { 
     DisposableChild c = new DisposableChild(); 
     DisposeOfIt(c); 

     Console.ReadKey(true); 
    } 

    public static void DisposeOfIt(DisposableParent p) 
    { 
     p.Dispose(); 
    } 
} 

只打印父處理。所以如果你使用這種方法,你必須小心控制對象的生命週期。

+0

感謝您的回答。我同意你的意見,我可以在繼承的類上實現IDisposable接口。這實際上是我想到的第一件事情。我只是好奇,如果有人會與另一個來,也許是一個更好的主意。如果在不久的將來沒有更好的事情,我會將你的答案標記爲已接受。 –

相關問題