我目前正在编写一个相当大的API,对于如何实现IDisposable感到困惑。在一个简化的场景中:
我在我的一个类中有一个Socket(称之为A),它显然需要处理,但是该类只有内部构造函数,因此我的用户只能通过创建一个更高级别对象(称之为B)的示例来创建它的示例,该对象反过来示例化A,从而获得新对象A的所有权。
我的直觉建议将对象A和B都设置为IDisposable,这样当用户在应用程序中释放我们的所有对象B时,A也会被释放,套接字也会被正确地释放。然而,由于这是一个API,它将允许我的用户在不释放所有对象B的情况下释放对象A和套接字,因此可能会给他们自己带来一些主要问题。
那我该怎么做呢?在我看来我只有坏的选择:
1.按照直觉实现IDisposable,并在文档中告诉我的用户不要愚蠢。(非常糟糕)
1.按照直觉实现IDisposable,但在整个应用程序中添加一些可怕的处置检查/异常以防万一(尽管在我的应用程序中,处置整个子部分对应用程序来说无论如何都是致命的)。
1.只在对象B中实现IDisposable,并添加一个内部Dispose方法来安全地处理A和套接字(似乎是最好的主意)。
我真的不知道我是否有任何其他的选择,所以我真的希望有人能给我建议。
谢谢。
3条答案
按热度按时间flvtvl501#
我的直觉建议将对象A和B都设置为IDisposable,这样当用户在应用程序中释放我们的所有对象B时,A也会被释放,套接字也会被正确地释放。然而,由于这是一个API,它将允许我的用户在不释放所有对象B的情况下释放对象A和套接字,因此可能会给他们自己带来一些主要问题。
使两者都实现
IDisposable
可能是最好的主意,并且清楚地说明了代码示例需要清理的事实。指示API的使用者在根/拥有对象(B)上调用Dispose
。要解决API的使用者意外地也在拥有的(A)示例上调用Dispose
的问题,您可以执行以下操作。"藏起来"
不要从根/拥有对象B公开拥有引用A,或者提供有限数量的传递方法,这些方法调用根并传递到拥有示例,然后再返回。如果你谈论的是真正有限数量的不会改变的方法/属性,这是很好的。
使用 Package 器和接口 Package 套接字访问(* 我在这里假设套接字是一个. net socket class,但是如果它是你自己的套接字类周围的对象实现,那么你的类已经是 Package 器了,不需要再创建另一个 Package 器了 *) Package 器应该实现
IDisposable
,接口应该只公开你希望客户端访问的内容。我不确定你在哪里创建套接字的示例,但是它们应该由被拥有的对象或者使用工厂模式来创建,这样所有者关系在创建后就能尽快建立。你可以保持类定义在内部,并且只向API公开一个接口。在我看来,这是最好的方法,如果您需要扩展您的API,还可以在将来进行灵活的更改。
44u64gxh2#
如果你不想让API用户处理你的socket,那就把它隐藏起来(做一些socket是私有的 Package 器或其他东西)。
否则,dispose通常是这样实现的,这样您就可以执行级联dispose,而不会真正介意是否已经释放了某些内容。
}
代码示例取自msdn,您可以在其中找到更详细的说明。
kh212irz3#
在实现
IDisposable
时要记住的一件重要的事情是不要处理不属于您的IDisposable
示例(那些不是您的类专门创建的示例)。因此,在您的情况下,选项3将是可取的。