隐式 <> 显式接口
Implicit <> Explicit interface问题的出现原因是接口的实现方式不同。显式接口实现是指在实现类中明确指定接口成员,而隐式接口实现则是不明确指定接口成员。
解决方法是在实现类中根据需要选择隐式或显式接口实现方式。如果接口成员在实现类中有多个实现,需要使用显式接口实现来明确指定不同的接口成员。
具体代码如下:
interface A { void A(); } interface B { void A(); } class Imp : A { public void A() // 隐式接口实现 { } } class Imp2 : A, B { public void A.A() // 显式接口实现 { } public void B.A() // 显式接口实现 { } }
所以,类Imp中的public void A是隐式接口实现,因为它是在该类中创建的,没有对接口A的引用(不是A.A())。如果它是A.A(),那么它就是显式接口实现。那么在使用上有什么区别呢?
区别在于在实现类Imp2中,需要使用正确的接口引用来调用Imp2的不同显式接口实现。这是因为两个接口都声明了相同的成员。
因此,在调用代码中,需要使用正确的接口引用来调用Imp2的不同显式接口实现。
隐式接口实现是指具有与接口相同签名的方法。
显式接口实现是指明确声明方法属于哪个接口。
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: implicit and explicit interface implementations
那么使用上有什么区别呢?为什么会优先选择其中之一?
当你有两个具有相同方法签名的接口时,你可以明确声明两个方法来实现每个接口的方法。或者,如果你想明确声明一个方法是为了实现接口,那么你可以显式声明。隐式声明存在的原因是大多数情况下,你不需要明确声明,接口实现可以被假定。
当您通过显式实现接口时,只有当对象被引用为该接口时,接口上的方法才可见:
public interface IFoo { void Bar(); } public interface IWhatever { void Method(); } public class MyClass : IFoo, IWhatever { public void IFoo.Bar() //显式实现 { } public void Method() //标准实现 { } }
如果在代码的某个地方有对该对象的引用:
MyClass mc = new MyClass(); mc.Bar(); //无法编译通过 IFoo mc = new MyClass(); mc.Bar(); //可以编译通过
对于标准实现,无论如何引用对象都没有关系:
MyClass mc = new MyClass(); mc.Method(); //编译通过
问题的出现是因为在显式实现接口时,只有通过接口引用对象才能访问接口上的方法。如果我们希望通过类的实例引用对象并访问接口上的方法,就会出现编译错误。
要解决这个问题,我们可以使用隐式实现接口。隐式实现接口允许我们使用类的实例引用对象,并且可以访问接口上的方法。下面是一个示例:
public interface IFoo { void Bar(); } public interface IWhatever { void Method(); } public class MyClass : IFoo, IWhatever { public void Bar() //隐式实现 { } public void Method() //标准实现 { } }
现在,我们可以通过类的实例引用对象并访问接口上的方法,而无需使用接口引用对象:
MyClass mc = new MyClass(); mc.Bar(); //编译通过 mc.Method(); //编译通过
通过这种方式,我们不再受限于只能通过接口引用对象来访问接口上的方法,从而提高了代码的灵活性和可读性。