如何让返回IMyClientAsync的包装方法支持using块释放资源?
问题描述
我定义了如下类:
public class MyClient : IMyClient, IMyClientAsync, IDisposable
编写了一个包装方法,返回IMyClientAsync类型:
IMyClientAsync GetClient() { return new MyClient(); }
但使用该方法的用户无法通过using(var client = MyWrapper.GetClient()){}这样的using块关闭客户端,因为对象实现IDisposable的信息丢失了。
解决方案
有几种可行的修改方式,按需选择:
让
IMyClientAsync继承IDisposable(推荐)
既然MyClient作为异步客户端需要被释放,对应的接口应该明确这个契约。修改接口定义:public interface IMyClientAsync : IDisposable { // 原有的异步方法声明 }这样包装方法返回的
IMyClientAsync本身就带有IDisposable特性,用户直接用using块即可,无需额外转换。修改包装方法的返回类型
如果不能修改接口,可以调整包装方法的返回类型:- 返回具体类型
MyClient:
缺点是暴露了具体实现类,不符合面向接口编程的原则。MyClient GetClient() { return new MyClient(); } - 返回
IDisposable:
用户需要先将对象转换为IDisposable GetClient() { return new MyClient(); }IMyClientAsync才能调用异步方法,使用起来较繁琐:using (var disposableClient = MyWrapper.GetClient()) { var asyncClient = (IMyClientAsync)disposableClient; // 调用asyncClient的异步方法 }
- 返回具体类型
使用模式匹配显式识别
IDisposable
不修改原有代码的情况下,用户可以通过模式匹配在using块中同时获取两种类型:if (MyWrapper.GetClient() is IMyClientAsync asyncClient and IDisposable disposable) { using (disposable) { // 使用asyncClient调用异步方法 } }这种方式无需改动原有代码,但写法相对啰嗦。
内容的提问来源于stack exchange,提问作者kosnkov
相关产品推荐
相关产品推荐

