明确实现接口和实现接口之间的区别是什么。
当您从界面派生类时,intellisense建议您同时执行这两个操作。
但是,有什么区别?
答案 0 :(得分:13)
另一方面:
如果您隐式实现,则意味着您的类的用户可以访问接口成员,而无需将其强制转换。
如果显式实现,客户端必须先将类转换为接口,然后才能访问成员。 以下是显式实现的示例:
interface Animal
{
void EatRoots();
void EatLeaves();
}
interface Animal2
{
void Sleep();
}
class Wombat : Animal, Animal2
{
// Implicit implementation of Animal2
public void Sleep()
{
}
// Explicit implementation of Animal
void Animal.EatRoots()
{
}
void Animal.EatLeaves()
{
}
}
您的客户代码
Wombat w = new Wombat();
w.Sleep();
w.EatRoots(); // This will cause a compiler error because it's explicitly implemented
((Animal)w).EatRoots(); // This will compile
答案 1 :(得分:10)
IDE为您提供了选项 - 两种方法都不常见。通过显式实现,成员不在(主)公共API上;如果接口没有直接绑定到对象的意图,这是很方便的。例如,ICustomTypeDescriptor
成员对常规调用者没有任何帮助 - 只对某些非常具体的代码有用,因此没有任何目的在公共API上使用它们导致混乱。
如果符合以下条件,这也很有用:
Foo
方法与您自己类型的Foo
方法之间存在冲突,它们意味着不同的事情最后一个点的典型示例是IEnumerable<T>
,它在接口层次结构中的两个级别都有GetEnumerator()
方法 - 通常使用类型化的(IEnumerator<T>
)版本来实现隐式实现,以及使用显式实现的无类型(IEnumerator
)版本。
答案 2 :(得分:6)
这是普通英语的区别:
假设您有一个接口Machine
,其函数为Run()
,另一个接口Animal
也有一个名为Run()
的函数。当然,当一台机器运行时,我们正在谈论它的启动,但是当一只动物跑来跑去时,我们正在谈论它的移动。那么当你有一个对象时会发生什么,让我们称之为Aibo
和Machine
的{{1}}? (顺便说一句,Aibo是一只机械狗。)当Animal
跑步时,他是否开始行动,或者是否会四处走动?明确地实现一个接口可以让你做出这样的区分:
Aibo
这里的问题是我不能简单地调用interface Animal
{
void Run();
}
interface Machine
{
void Run();
}
class Aibo : Animal, Machine
{
void Animal.Run()
{
System.Console.WriteLine("Aibo goes for a run.");
}
void Machine.Run()
{
System.Console.WriteLine("Aibo starting up.");
}
}
class Program
{
static void Main(string[] args)
{
Aibo a = new Aibo();
((Machine)a).Run();
((Animal)a).Run();
}
}
,因为我的两个函数实现都显式附加到接口。这是有道理的,因为否则编译器将如何知道要调用哪一个?相反,如果我想直接调用a.Run()
上的Run()
函数,我必须还在没有显式界面的情况下实现该函数。
答案 3 :(得分:4)
显式将放置IInterfaceName。在所有接口实现的前面。如果您需要实现两个包含冲突名称/签名的接口,这将非常有用。
更多信息here。
答案 4 :(得分:1)
显式实现将完全限定名称放在函数名称上考虑此代码
public interface IamSam
{
int foo();
void bar();
}
public class SamExplicit : IamSam
{
#region IamSam Members
int IamSam.foo()
{
return 0;
}
void IamSam.bar()
{
}
string foo()
{
return "";
}
#endregion
}
public class Sam : IamSam
{
#region IamSam Members
public int foo()
{
return 0;
}
public void bar()
{
}
#endregion
}
IamSam var1;
var1.foo() returns an int.
SamExplicit var2;
var2.foo() returns a string.
(var2 as IamSam).foo() returns an int.
答案 5 :(得分:0)
您可以直接从MSDN
开始答案 6 :(得分:0)
不同之处在于您可以从多个接口继承一个类。这些接口可能具有相同的方法签名。显式实现允许您根据使用哪个接口来更改实现。
答案 7 :(得分:0)
当接口与类功能正交时,显式接口实现(隐藏实现除非您显式转换)最有用。也就是说,行为无关。
例如,如果你的类是Person并且接口是ISerializable,那么处理Person属性的人通过Intellisense看到一些叫做'GetObjectData'的奇怪东西就没什么意义了。因此,您可能希望显式实现该接口。
另一方面,如果你的person类碰巧实现了IAddress,那么直接在Person实例上看到像AddressLine1,ZipCode等成员(隐式实现)是完全合理的。