C#泛型是一種高復用性、安全和高效的技術,通過類型參數可以將參數的聲明、實現推遲到客戶代碼中。但是這種延遲卻降低了類型參數在泛型定義中的可操作性。例如資源釋放。 但是如果T實現了IDisposable介面,則上面代碼可能存在資源泄露的風險。但是由於不知道T是否實現了IDisposable介面,所以不 ...
C#泛型是一種高復用性、安全和高效的技術,通過類型參數可以將參數的聲明、實現推遲到客戶代碼中。但是這種延遲卻降低了類型參數在泛型定義中的可操作性。例如資源釋放。
public interface IWorker { void Operate(); } public class GenericWorker<T> where T : IWorker , new() { public void GetResult() { T worker=new T(); worker.Operate(); } }
但是如果T實現了IDisposable介面,則上面代碼可能存在資源泄露的風險。但是由於不知道T是否實現了IDisposable介面,所以不能直接釋放資源。對於這個問題可以使用下麵語法,利用編譯器的特性進行資源釋放:
1 public void GetResult() 2 { 3 T worker = new T(); 4 using (worker as IDisposable) 5 { 6 worker.Operate(); 7 } 8 }
對於上面的代碼,編譯期會分配一個本地變數,存放worker轉為IDisposable的結果。如果T未實現IDisposable介面,那麼本地變數為null,那麼編譯器就不會執行Dispose(),否則會執行Dispose()。
若泛型類中需要實例化某個類型參數為成員變數,那麼情況就會變複雜。此時的成員變數可能需要釋放資源,對於這種情況可以通過使泛型類實現IDisposable介面解決:
1 public sealed class GenericWorker<T> : IDisposable 2 where T : IWorker, new() 3 { 4 private T worker; 5 6 public void GetResult() 7 { 8 if (worker == null) 9 worker = new T(); 10 using (worker as IDisposable) 11 { 12 worker.Operate(); 13 } 14 } 15 16 public void Dispose() 17 { 18 using (IDisposable tmp = worker as IDisposable) 19 { 20 21 } 22 } 23 }
不過上面代碼可以改為IDisposable模式就更完美了。