Difference between implicit and explicit implementation of C# interfaces
显式实现接口和实现接口之间的区别是什么?
从接口派生类时,IntelliSense建议您同时执行这两项操作。
但是,有什么区别?
另一方面:
如果隐式实现,则意味着您的类的用户可以访问接口成员,而不必强制转换它。
如果它是显式实现的,那么在能够访问成员之前,客户机必须将类强制转换为接口。下面是一个显式实现的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 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() { } } |
您的客户代码
1 2 3 4 | 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 |
IDE为您提供了两种选择——这两种选择都不常见。通过显式实现,成员不在(主)公共API上;如果接口与对象的意图没有直接联系,这很方便。例如,
这在以下情况下也很有用:
- 接口的
Foo 方法和您自己类型的Foo 方法之间存在冲突,它们的含义不同 - 其他接口之间存在签名冲突
最后一点的典型例子是
以下是简单英语的区别:
假设您有一个接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | 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(); } } |
这里的要点是,我不能简单地调用
Explicit将放置iInterfaceName。在所有接口实现的前面。如果您需要实现两个包含冲突名称/签名的接口,那么这将非常有用。
更多信息在这里。
显式实现将完全限定名放在函数名上考虑此代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | 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. |
显式接口实现(除非显式强制转换,否则实现是隐藏的)在接口与类功能正交时最有用。也就是说,行为上无关。
例如,如果您的类是Person,并且接口是可ISerializable的,那么对于处理Person属性的人来说,通过IntelliSense看到一些奇怪的称为"GetObjectData"的东西没有多大意义。因此,您可能希望显式实现接口。
另一方面,如果您的Person类恰好实现了IAddress,那么直接在Person实例上看到AddressLine1、ZipCode等成员(隐式实现)是非常有意义的。
区别在于,您可以从几个接口继承一个类。这些接口可能具有相同的方法签名。显式实现允许您根据调用它的接口更改实现。
给你,直接从msdn来