在c#中隐式和显式实现接口有什么不同?
什么时候用隐式,什么时候用显式?
这两者之间有什么利弊吗?
微软的官方指南(来自第一版框架设计指南)指出,不建议使用显式实现,因为它会给代码带来意想不到的行为。
我认为这个准则在前ioc时代是非常有效的,当你不把东西作为接口传递的时候。
有人能谈谈这方面的问题吗?
在c#中隐式和显式实现接口有什么不同?
什么时候用隐式,什么时候用显式?
这两者之间有什么利弊吗?
微软的官方指南(来自第一版框架设计指南)指出,不建议使用显式实现,因为它会给代码带来意想不到的行为。
我认为这个准则在前ioc时代是非常有效的,当你不把东西作为接口传递的时候。
有人能谈谈这方面的问题吗?
当前回答
实现接口的每个类成员都导出一个语义上类似于VB的声明。NET接口声明被编写,例如:
Public Overridable Function Foo() As Integer Implements IFoo.Foo
尽管类成员的名称经常与接口成员的名称相匹配,而且类成员通常是public的,但这些都不是必需的。你也可以声明:
Protected Overridable Function IFoo_Foo() As Integer Implements IFoo.Foo
In which case the class and its derivatives would be allowed to access a class member using the name IFoo_Foo, but the outside world would only be able to access that particular member by casting to IFoo. Such an approach is often good in cases where an interface method will have specified behavior on all implementations, but useful behavior on only some [e.g. the specified behavior for a read-only collection's IList<T>.Add method is to throw NotSupportedException]. Unfortunately, the only proper way to implement the interface in C# is:
int IFoo.Foo() { return IFoo_Foo(); }
protected virtual int IFoo_Foo() { ... real code goes here ... }
没那么好。
其他回答
隐式是指通过类上的成员定义接口。显式是指在接口上的类中定义方法。我知道这听起来令人困惑,但我的意思是: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.
我使用显式主要是为了保持实现的简洁,或者当我需要两个实现时。不管怎样,我很少使用它。
我相信有更多的理由使用/不使用explicit,其他人会发布。
请参阅本帖的下一篇文章,了解每一篇文章背后的优秀推理。
隐式接口实现是指具有与接口相同签名的方法。
显式接口实现是显式声明方法属于哪个接口的地方。
interface I1
{
void implicitExample();
}
interface I2
{
void explicitExample();
}
class C : I1, I2
{
void implicitExample()
{
Console.WriteLine("I1.implicitExample()");
}
void I2.explicitExample()
{
Console.WriteLine("I2.explicitExample()");
}
}
MSDN:隐式和显式接口实现
隐式定义是将接口需要的方法/属性等直接作为公共方法添加到类中。
显式定义强制只在直接使用接口而不是底层实现时才公开成员。在大多数情况下,这是首选。
By working directly with the interface, you are not acknowledging, and coupling your code to the underlying implementation. In the event that you already have, say, a public property Name in your code and you want to implement an interface that also has a Name property, doing it explicitly will keep the two separate. Even if they were doing the same thing I'd still delegate the explicit call to the Name property. You never know, you may want to change how Name works for the normal class and how Name, the interface property works later on. If you implement an interface implicitly then your class now exposes new behaviours that might only be relevant to a client of the interface and it means you aren't keeping your classes succinct enough (my opinion).
如果显式实现,则只能通过与接口类型相同的引用引用接口成员。实现类类型的引用不会公开这些接口成员。
如果实现的类不是公共的,除了用于创建类的方法(可以是工厂或IoC容器),并且除了接口方法(当然),那么我认为显式实现接口没有任何好处。
否则,显式实现接口将确保不使用对具体实现类的引用,从而允许您在以后更改该实现。“确保”,我想,是“优势”。一个分解良好的实现可以在没有显式实现的情况下完成这一点。
在我看来,缺点是您会发现自己在实现代码中对接口进行类型转换,而接口可以访问非公共成员。
就像许多事情一样,优势就是劣势(反之亦然)。显式实现接口将确保不会公开具体的类实现代码。
实现接口的每个类成员都导出一个语义上类似于VB的声明。NET接口声明被编写,例如:
Public Overridable Function Foo() As Integer Implements IFoo.Foo
尽管类成员的名称经常与接口成员的名称相匹配,而且类成员通常是public的,但这些都不是必需的。你也可以声明:
Protected Overridable Function IFoo_Foo() As Integer Implements IFoo.Foo
In which case the class and its derivatives would be allowed to access a class member using the name IFoo_Foo, but the outside world would only be able to access that particular member by casting to IFoo. Such an approach is often good in cases where an interface method will have specified behavior on all implementations, but useful behavior on only some [e.g. the specified behavior for a read-only collection's IList<T>.Add method is to throw NotSupportedException]. Unfortunately, the only proper way to implement the interface in C# is:
int IFoo.Foo() { return IFoo_Foo(); }
protected virtual int IFoo_Foo() { ... real code goes here ... }
没那么好。