C# 接口继承是一种糟糕的做法吗?

C# 接口继承是一种糟糕的做法吗?,c#,oop,design-patterns,inheritance,C#,Oop,Design Patterns,Inheritance,我想知道下面的代码是否显示了一种不好的做法(关于接口继承): 在这里,我想要两件事: 1.使用C#的using语句,这样我就可以优雅地处理具体对象的依赖项(无需将任何内容转换为IDisposable)。 2.使用工厂方法创建一个具体的对象,所以我只能使用接口 分开,两者都是已知的好做法,但在一起?我没有发现任何东西说这是错误的(MSDN-界面设计),但我认为这听起来不好 如果您对此有任何评论,我将不胜感激。如果这是一种不好的做法,那么使用这种方法会遇到什么样的问题 谢谢 我认为这是正确的。工厂隐

我想知道下面的代码是否显示了一种不好的做法(关于接口继承):

在这里,我想要两件事: 1.使用C#的using语句,这样我就可以优雅地处理具体对象的依赖项(无需将任何内容转换为IDisposable)。 2.使用工厂方法创建一个具体的对象,所以我只能使用接口

分开,两者都是已知的好做法,但在一起?我没有发现任何东西说这是错误的(MSDN-界面设计),但我认为这听起来不好

如果您对此有任何评论,我将不胜感激。如果这是一种不好的做法,那么使用这种方法会遇到什么样的问题


谢谢

我认为这是正确的。工厂隐藏了实际实例化的类,因此
IFoo
必须继承
IDisposable
,客户端才能调用
Dispose()
。使用这个类,客户机可以并且应该完全不知道实例化的实际类。所有相关信息都应由界面携带,包括处理的需要。

这是完全有效的。这正是接口的用途。他们定义合同。可以使用多个分包合同来构建合同

在野外,没有绝对的好的或坏的做法,每种做法都有其优点和缺点。
只有将实践应用于具体问题时,实践才会变成好的或坏的(阅读:not
IFoo

public bool很好(i实践实践)
其中TContext:reallworldapplication,new();
因此,与其尝试寻找MSDN的指导,不如问自己以下问题:

这是否解决了问题并使代码更易于阅读?

如果答案是肯定的,那就去做吧

就我个人而言,我喜欢这种方法。如果
IFoo
的合同要求妥善处理(想想:
IGraphicalObject
IResource
IConnection
),那么明确这一点是一个非常好的设计决策

不要被教条所束缚:使用接口编程可以减少对具体实现的依赖,但仅使用接口编程可能是一场噩梦。讲道理,就是这样

更新 您可以使用Google在.NET Framework本身中查找从
IDisposable
继承的所有接口:

正如我上面所说的,这通常是针对已知消耗资源的实体完成的,例如数据库连接、非托管对象包装器、图形对象等等

Dispose()
强加给一个没有可处理的类是个坏主意。

在这种情况下,最好将其保留为可选,并检查对IDisposable的支持。

从技术上讲,此解决方案一切正常

从语义的角度来看,您可以认为,
IDisposable
的需要是一个实现细节,与类的实际契约无关

您可以将对象强制转换为
IDisposable
,并仅在实现
IDisposable
时调用
Dispose()

var disposable = foo as IDisposable;

if (disposable != null)
    disposable.Dispose();

但在本例中,我将按照您的建议使用接口继承。这并不是最干净的方法,但它能完美地为您完成这项工作,并且需要更少的代码。

几乎所有可丢弃的.NET对象基本上都能做到这一点。请看,您可以使用Google在.NET Framework本身中找到这样的接口。答案很好,伙计们,非常感谢!在野外肯定有很多不好的做法。是的,但是如果没有看到它的实际应用,你不能100%地说它是不好的做法。练习是一个很滑的词;在某些情况下,通常认为不好的做法是在具体情况下做某事的最佳方式。我只是说,为自己着想(当然,只有当你相信自己的想法时,这才有效。如果我不确定,我会描述我的确切情况,寻求StackOverflow方面的建议,但不会询问“实践”)。@Henk:我做了一个编辑来强调这一点,如果实现接口的对象可能需要知道何时有人使用它,特别是如果最后一个使用它的实体可能不知道它的特定类型,那么接口应该继承IDisposable。即使99.9%的接口实现都不关心,忽略IDisposable可能会导致最后几年出现问题。IEnumerator就是一个很好的例子。大多数枚举器不在乎什么时候不再需要它们,但有一些类型确实如此。如果IEnumerator没有实现IDisposable,那么使用枚举数的代码将不得不……或者尝试将枚举数强制转换为IDisposable,并在转换成功时调用Dispose,或者跳过Dispose,希望这不会造成像打开文件之类的问题。通常,让IEnumerator继承IDisposable并让消费者无条件地进行处置要比检查是否有必要进行处置并仅在必要时调用处置更快。
public bool IsGood<TContext>(IPractice practice)
    where TContext : RealWorldApplication, new();
var disposable = foo as IDisposable;

if (disposable != null)
    disposable.Dispose();