在C#中隐式和显式实现接口有何区别?
什么时候应该使用隐式,什么时候应该使用显式?
彼此之间是否有优点和/或缺点?
Microsoft的官方指南(来自第一版Framework Design Guidelines )指出, 不建议使用显式实现 ,因为它会给代码带来意想不到的行为。
我认为,在您未将事物作为接口传递时 ,该指南在IoC之前非常有效 。
任何人都可以谈谈这方面吗?
#1楼
显式接口实现的一个重要用途是在需要实现具有混合可见性的接口时。
C#内部接口一文很好地解释了该问题和解决方案。
例如,如果要保护应用程序层之间的对象泄漏,则可以使用此技术指定可能导致泄漏的成员的不同可见性。
#2楼
隐式是当您通过类中的成员定义接口时。 显式的是您在接口上的类中定义方法时。 我知道这听起来令人困惑,但这就是我的意思: IList.CopyTo
将隐式实现为:
public void CopyTo(Array array, int index)
{
throw new NotImplementedException();
}
并明确表示为:
void ICollection.CopyTo(Array array, int index)
{
throw new NotImplementedException();
}
不同之处在于,隐式实现允许您通过将接口强制转换为该类以及接口本身来创建的类来访问该接口。 显式实现仅允许您通过将接口强制转换为接口本身来访问该接口。
MyClass myClass = new MyClass(); // Declared as concrete class
myclass.CopyTo //invalid with explicit
((IList)myClass).CopyTo //valid with explicit.
我主要使用显式的来保持实现的整洁,或者在我需要两个实现时。 无论如何,我很少使用它。
我确信还有更多理由使用/不使用其他人会张贴的明确内容。
有关每个主题背后的出色推理,请参阅此线程中的下一篇文章 。
#3楼
隐式定义将只是将接口所需的方法/属性等作为公共方法直接添加到类中。
显式定义仅在直接使用接口而不是基础实现时才强制成员公开。 在大多数情况下,这是首选。
- 通过直接使用该接口,您无需确认,而是将代码耦合到基础实现。
- 如果您的代码中已经有一个公共属性Name,并且您想要实现一个也具有Name属性的接口,则显式地将两者分开。 即使他们在做同样的事情,我仍然将显式调用委托给Name属性。 您永远不会知道,您可能想更改Name在普通类中的工作方式以及Name(接口属性)以后的工作方式。
- 如果隐式实现一个接口,则您的类现在将暴露可能仅与该接口的客户端相关的新行为,这意味着您的类不够简洁(我认为)。
#4楼
如果您明确实现,则只能通过接口类型的引用来引用接口成员。 作为实现类类型的引用不会公开那些接口成员。
如果您的实现类不是公共的,除了用于创建该类的方法(可以是工厂或IoC容器)之外,而且除了接口方法(当然)外,那么我看不出显式实现的任何优势接口。
否则,显式实现接口可确保不使用对具体实现类的引用,从而允许您稍后更改该实现。 我想,“确定”是“优势”。 构造合理的实现无需显式实现即可完成此操作。
在我看来,缺点是您会发现自己在实现代码中可以访问非公共成员的接口强制类型转换。
与许多事物一样,优势是劣势(反之亦然)。 显式实现接口将确保不暴露您的具体类实现代码。
#5楼
除了已经提供的出色答案外,在某些情况下,还要求显式实现以使编译器能够确定所需的内容。 以IEnumerable<T>
为例,它可能经常出现。
这是一个例子:
public abstract class StringList : IEnume