当前位置: 首页 > 编程语言 > C#

如何解释不同的实现需求?share

时间:2023-04-10 14:30:27 C#

如何解释不同的实施需求?假设我有一个包含两个具体类的接口。具体需要实现IDisposable。是否应该修改接口以实现IDisposable以获得类的好处,或者接口的使用者是否必须执行运行时检查可处置性?我假设应该修改接口,因为它是一个简单的更改(特别是如果它是一个新接口)但是我也可以看到在更改设计以适应特定实现时可能存在的liskov违规(特别是如果其他类或类必须抛出不支持的例外)如果框架本身有任何迹象,那么使接口实现IDisposable的适当性取决于可处置性是否是实现接口定义的契约的必要属性。少数框架接口确实实现了IDisposable,包括:系统。ComponentModel.IContainer就其本质而言,这些接口通常定义会消耗资源并因此需要释放的结构。从这个意义上讲,处理资源可以看作是实现契约的一个组成部分,而不是实现接口的具体类的实现细节。例如,IResourceReader将从资源中读取,关闭资源是履行契约的必要部分。相反,在框架中非常常见,具体类直接实现IDisposable(而不是通过另一个接口)。对于框架类,可以通过反射查询:foreach(varvintypeof(/*anytype*/).Assembly.GetTypes().Where(a=>a.IsClass&&typeof(IDisposable).IsAssignableFrom(a)&&a.GetInterfaces().Where(i=>i!=typeof(IDisposable)).All(i=>!typeof(IDisposable).IsAssignableFrom(i)))){foreach(varsinv.GetInterfaces())控制台.WriteLine(v.FullName+":"+s.Name);通常,这些类的实现会消耗实现接口契约所带来的资源。例如,System.Data.SqlClient.SqlDataAdapter实现了IDbDataAdapter和IDisposable;IDbDataAdapter完全有可能不需要释放,但是SqlDataAdapter的实现需要消耗和释放资源。在您的情况下,您声明有两个类实现您的接口,一个需要实现IDisposable而另一个不需要。鉴于不,根据定义,处置资源的能力不是实现接口要求的必要条件;接下来,接口本身不应该实现IDisposable。顺便说一下,Dispose()不应抛出异常(请参阅CA1065:不要在意外位置抛出异常。)如果实现IDisposable的类的实例没有可处理的资源,它可以简单地返回;满足资源释放的所有后置条件。无需抛出NotSupportedException。附录第二个可能的考虑因素是接口的预期用途。例如,数据库场景中常用的模式如下:System.Data.IDbCommandcmd=...;using(varrdr=cmd.ExecuteReader())//返回IDataReader(IDisposable){while(rdr.Read()){...}}//dispose如果IDataReader没有实现IDisposable,则需要等效代码更复杂:System.Data.IDbCommandcmd=...;System.Data.IDataReaderrdr;尝试{rdr=cmd.ExecuteReader();while(rdr.Read()){...};}finally{if(rdrisIDisposable)((IDisposable)rdr).Dispose();如果预期这种类型的使用是常见的,如果不是所有实现都预期实现IDisposable,并且也可能将接口IDisposable视为一种特殊情况。我在阅读MarkSeemann关于依赖注入的书时找到了答案。接口上的IDisposable自动成为泄漏抽象,因为IDisposable只是一个实现细节。也就是说,并非所有接口都是抽象的,因此——严格以接口编程的名义——在某些情况下接口必须实现IDisposable。虽然带有接口的具体工具ID更可取,但在这两种情况下,解决方案都是对资源创建粗粒度的抽象。然后抽象的每个方法实现都会创建和处理资源,从而减轻消费者做同样事情的负担。我喜欢这种方法,因为它降低了消费者生命周期管理的复杂性(实际上应该没有,尤其是在DI中)。为了在上述场景中实现DI,您可能需要注入一个允许每个方法实例化临时依赖项的工厂。以上就是C#学习教程:不同的实现需求如何解释?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: