在C#中展示继承接口实现的最佳方式是什么?

3

给定以下接口:

interface IFoo
{
    void Foo();
}

interface IBar : IFoo
{
    void Bar();
}

怎样最好地表明一个类实现了IBar接口?

方法A:

class Implementation : IBar { ... }

这个看起来更简单清晰,但它并没有说明 Implementation 实现了 IFoo

方法 B:

class Implementation : IBar, IFoo { ... }

这似乎是最具信息量的,但额外的信息真的必要吗?
7个回答

6
额外信息对编译器来说并不必要,但对于代码读者来说可能会有帮助,因为读者不需要知道 IBar 扩展了 IFoo。在框架中的一个例子是 List<T> 实现了 <IList<T>ICollection<T>IEnumerable<T>,即使 IList<T> 扩展了 ICollection<T>IEnumerable<T>编辑:我认为至少对我来说,列出两个接口的主要原因是你通常不会想到接口之间会互相继承。当你从一个类派生时,你期望你正在继承可能被继承的行为。如果您感兴趣,您可以跟踪类层次结构上的派生。使用接口更不寻常,因此您可能会错过连接而不会看得太多。同时列出它们可以解决这个问题,而不会带来太多麻烦。

@tvanfosson:框架这样做的原因与数据绑定有关吗? - Mitch Wheat
@Mitch - 是的,如果您明确实现了任何接口,那么也是必要的。但是,如果我有一个接口继承层次结构,我可能会列出这些接口。为什么要让读者猜测哪些接口被实现了呢? - tvanfosson

6

个人而言,我会选择前者。对于后者,假设你处于这样一种情况,你有一堆派生类:

class DerivedA : Implementation, IBar, IFoo { ... }
class DerivedB : Implementation, IBar, IFoo { ... }
class DerivedC : Implementation, IBar, IFoo { ... }
class DerivedD : Implementation, IBar, IFoo { ... }

然后,您对Implementation的要求发生了变化,现在需要实现另一个接口,例如IBaz(只要提供非抽象实现即可),而不必影响任何派生类,那么您有两个选择:
  1. 保留所有派生类定义而没有显式声明新接口信息,在这种情况下,根据标准,类定义现在是不正确的,并且如果人们期望始终遵循标准,则可能具有误导性。
  2. 查找所有派生类及其派生类,并修复它们的声明。这需要时间,有些容易出错,难以完全做到,将您的单个文件更改转换为多文件提交。
这两个选项都不太理想,所以我会选择不使您陷入任何一种情况的选项。只需声明最终的接口即可。

从类派生时,我不会担心这个问题。但是在接口的情况下,您通常不希望继承并列出两者将使其清晰明了。 - tvanfosson

1
我会选择A。你可以在类本身中看到需要实现哪些方法,IDE中的导航工具将帮助你完成其余部分。
如果进行任何重构(例如,如果替换IBar或将其拆分为两个),B将无法维护。

1

你已经在IBar中实现了IFoo,这意味着你甚至不需要指定你的具体实现类实现了IFoo;CLR可以推断出来,如果你在程序集上使用Reflector,你会看到它指定Implementation同时实现了IFooIBar,即使你使用了方法A。

所以采用方法A。


0

我认为方法A已经足够明确了,因为(在VS.NET中)你可以非常快速地确定IBar实现了IFoo。


0

除了可读性和VB.NET的差异(请参见Kathleen Dollard的评论),还存在一种需要(B)的数据绑定情况。细节已经从我的脑海中溜走了(我会编辑,除非有人比我更快...)。

我认为这就是.NET Framework集合明确实现其派生接口的原因。


0

我会选择方法A,因为在类定义的派生列表中列出接口意味着您正在该类中提供其实现。如果您不打算提供IFoo的替代实现,则不应将其包含在列表中,除非您需要它作为简单的“标记接口”。然而,即使如此,在运行时,“is”运算符(返回true或false)或“as”关键字(返回对象或null)将告诉您对象是否可以转换为IFoo。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接