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模式就更完美了。