C#接口的隐式和显式实现之间的区别[重复]
Posted
技术标签:
【中文标题】C#接口的隐式和显式实现之间的区别[重复]【英文标题】:Difference between implicit and explicit implementation of C# interfaces [duplicate] 【发布时间】:2010-10-17 07:02:39 【问题描述】:显式实现接口和实现接口有什么区别。
当您从接口派生类时,intellisense 建议您两者都做。
但是,有什么区别呢?
【问题讨论】:
【参考方案1】:另一方面:
如果您隐式实现,则意味着您的类的用户可以访问接口成员,而无需他们进行强制转换。
如果它是显式实现的,则客户端必须先将您的类转换为接口,然后才能访问成员。 下面是一个显式实现的例子:
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
【讨论】:
【参考方案2】:IDE 为您提供了 选项 来做任何一个 - 两者都做是不寻常的。通过显式实现,成员不在(主要)公共 API 上;如果接口不直接与对象的意图相关联,这很方便。例如,ICustomTypeDescriptor
成员对普通调用者并没有太大帮助 - 仅对一些非常具体的代码有帮助,因此将它们放在公共 API 上造成混乱是没有意义的。
这在以下情况下也很有用:
接口的Foo
方法和您自己类型的Foo
方法之间存在冲突,它们的含义不同
其他接口之间存在签名冲突
最后一点的典型例子是IEnumerable<T>
,它在接口层次结构的两个层次上都有一个GetEnumerator()
方法——常见的是使用隐式实现来实现类型化的(IEnumerator<T>
)版本,而非类型化的(IEnumerator
) 版本使用显式实现。
【讨论】:
当您的类需要实现您不想从程序集中公开导出的内部接口时,显式实现也很有用。【参考方案3】:这是简单英语的区别:
假设你有一个接口Machine
,它有一个函数Run()
,另一个接口Animal
也有一个函数Run()
。当然,当机器运行时,我们谈论的是它的启动,但是当动物奔跑时,我们谈论的是它四处移动。那么当你有一个对象时会发生什么,我们称它为Aibo
,它既是Machine
,又是Animal
? (顺便说一句,Aibo 是一只机械狗。)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()
,因为我的两个函数实现都显式附加到一个接口。这是有道理的,否则编译器怎么知道该调用哪一个呢?相反,如果我想直接在 Aibo
上调用 Run()
函数,我将不得不也在没有显式接口的情况下实现该函数。
【讨论】:
【参考方案4】:显式将IInterfaceName。在所有接口实现的前面。如果您需要实现两个包含冲突的名称/签名的接口,这将非常有用。
更多信息here.
【讨论】:
【参考方案5】:显式实现将完全限定名称放在函数名上考虑此代码
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.
【讨论】:
【参考方案6】:给你,直接来自MSDN
【讨论】:
【参考方案7】:不同之处在于您可以从多个接口继承一个类。这些接口可能具有相同的方法签名。显式实现允许您根据调用它的接口来更改您的实现。
【讨论】:
【参考方案8】:显式接口实现,除非您显式强制转换,否则该实现是隐藏的,当接口与类功能正交时最有用。也就是说,行为上不相关。
例如,如果您的类是 Person 并且接口是 ISerializable,那么处理 Person 属性的人通过 Intellisense 看到名为“GetObjectData”的奇怪东西就没有多大意义。因此,您可能希望显式实现该接口。
另一方面,如果您的 person 类碰巧实现了 IAddress,那么直接在 Person 实例上查看 AddressLine1、ZipCode 等成员(隐式实现)非常有意义。
【讨论】:
以上是关于C#接口的隐式和显式实现之间的区别[重复]的主要内容,如果未能解决你的问题,请参考以下文章