显示实现和隐式实现接口的区别(Implicit and Explicit Interface Implementations)
来源:互联网 发布:hdmi切换器品牌 知乎 编辑:程序博客网 时间:2024/05/09 11:35
Implicit and Explicit Interface Implementations
Rate This
mhop
13 Dec 2006 2:59 AM
- 19
As I was putting together a post on IEnumerable andIEnumerator Iwas reminded of the subtleties of implicit and explicit interfaceimplementations. C# does not support multiple inheritance, but a class has theoption of implementing one or more interfaces. One challenge with interfaces isthat they may include methods that have the same signatures as existing classmembers or members of other interfaces. Explicit interface implementations canbe used to disambiguate class and interface methods that would otherwiseconflict. Explicit interfaces can also be used to hide the details of aninterface that the class developer considers private.
Disambiguating Methods
Let's look at an example of method disambiguation. In Listing 1 we havestarted to write a class calledC that implements interfacesI1and I2, each of which defines a methodA().
Listing 1. Class C implements interfaces I1 and I2.
interface I1
{
void A();
}
interface I2
{
void A();
}
class C : I1, I2
{
public void A()
{
Console.WriteLine("C.A()");
}
}
In this case, A() is a public class member that implicitlyimplements a member of both interfaces. A() can be invokedthrough either interface or through the class itself as follows:
Listing 2. A() can be invoked from I1, I2, or C.
C c = new C();
I1 i1 = (I1)c;
I2 i2 = (I2)c;
i1.A();
i2.A();
c.A();
The output from this code is
C.A()
C.A()
C.A()
This works fine if you want A() to do the same thing in bothinterfaces. In most cases, however, methods in different interfaces havedistinct purposes requiring wholly different implementations. This is whereexplicit interface implementations come in handy. To explicitly implement aninterface member, just use its fully qualified name in the declaration. A fullyqualified interface name takes the form
InterfaceName.MemberName
In Listing 3 we add an explicit implementation of I1'sA()method.
Listing 3. Class C explicitly implements I1.A().
class C : I1, I2
{
public void A()
{
Console.WriteLine("C.A()");
}
void I1.A()
{
Console.WriteLine("I1.A()");
}
}
Now when we run the statements from Listing 2 we get
I1.A()
C.A()
C.A()
When an interface method is explicitly implemented, it is no longervisible as a public member of the class. The only way to access it is throughthe interface. As an example, suppose we deleted the implicitimplementation ofA() as shown in Listing 4:
Listing 4. Class C does not implicitly implement A()
class C : I1, I2
{
void I1.A()
{
Console.WriteLine("I2.A()");
}
}
In this case we would get a compile error saying that C fails toimplementI2.A(). We could fix this error by changing the first line to
class C : I1
but we'd get another compile error when trying to invoke A() as amember of C:
C c = new C();
c.A();
This time the compiler would report that class C does not contain adefinition for methodA(). We get the error because the explicitimplementation ofI1.A() hides A() from the class. The only wayto callI1.A() now is through C's I1 interface:
C c = new C();
I1 i1 = (I1)c;
i1.A();
Explicit interface implementations are sometimes necessary when classesimplement multiple interfaces with conflicting member definitions. A commonexample involves collection enumerators that implementSystem.Collections.IEnumeratorandSystem.Collections.Generic.IEnumerator. In this case both interfaces specify a get-accessor for theCurrentproperty. To create a class that compiles, at least one of the twoget-accessors must be explicitly implemented.
Hiding Interface Details.
In some cases explicit interface implementation can be useful even whendisambiguation is unnecessary. One example is to use an explicit implementationto hide the details of an interface that the class developer considers private.While the level of privacy is not as great as that afforded by the privatekeyword, it can be useful in some circumstances. Listing 5 shows a commonpattern involvingIDisposable.In this case, the Dispose() method is hidden by explicit implementationbecause the method is really an implementation detail that is notgermane to the users of classMyFile. At the very least, the explicitimplementation keeps the interface members out of the class'Intellisenselist.
Listing 5. Using explicit implementation to hide the details ofIDisposable.
interface IDisposable
{
void Dispose();
}
class MyFile : IDisposable
{
void IDisposable.Dispose()
{
Close();
}
public voidClose()
{
// Dowhat's necessary to close the file
System.GC.SuppressFinalize(this);
}
}
You can read more about implicit and explicit interface implementations inthisMSDNTutorial or in Version 1.2 ofthe C# Language Specification.
Hope this helps.
-Mike Hopcroft
转自 http://bbs.csdn.net/topics/320002324
在MSDN上原文:http://msdn.microsoft.com/en-us/library/ms173157.aspx
如果类实现两个接口,并且这两个接口包含具有相同签名的成员,那么在类中实现该成员将导致两个接口都使用该成员作为它们的实现。例如:
C# 复制代码
interface IControl
{
void Paint();
}
interface ISurface
{
void Paint();
}
class SampleClass : IControl, ISurface
{
// Both ISurface.Paint and IControl.Paint call this method.
public void Paint()
{
}
}
然而,如果两个接口成员执行不同的函数,那么这可能会导致其中一个接口的实现不正确或两个接口的实现都不正确。可以显式地实现接口成员 -- 即创建一个仅通过该接口调用并且特定于该接口的类成员。这是使用接口名称和一个句点命名该类成员来实现的。例如:
C# 复制代码
public class SampleClass : IControl, ISurface
{
void IControl.Paint()
{
System.Console.WriteLine("IControl.Paint");
}
void ISurface.Paint()
{
System.Console.WriteLine("ISurface.Paint");
}
}
类成员 IControl.Paint 只能通过 IControl 接口使用,ISurface.Paint 只能通过 ISurface 使用。两个方法实现都是分离的,都不可以直接在类中使用。例如:
C# 复制代码
SampleClass obj = new SampleClass();
//obj.Paint(); // Compiler error.
IControl c = (IControl)obj;
c.Paint(); // Calls IControl.Paint on SampleClass.
ISurface s = (ISurface)obj;
s.Paint(); // Calls ISurface.Paint on SampleClass.
显式实现还用于解决两个接口分别声明具有相同名称的不同成员(如属性和方法)的情况:
C# 复制代码
interface ILeft
{
int P { get;}
}
interface IRight
{
int P();
}
为了同时实现两个接口,类必须对属性 P 和/或方法 P 使用显式实现以避免编译器错误。例如:
C# 复制代码
class Middle : ILeft, IRight
{
public int P() { return 0; }
int ILeft.P { get { return 0; } }
}
自己动手试一试的冲动有没有??(~
- 显示实现和隐式实现接口的区别(Implicit and Explicit Interface Implementations)
- C.Interface.And.Implementations—stack的实现
- C.Interface.And.Implementations—Atom的实现
- C.Interface.And.Implementations—exception的实现
- C.Interface.And.Implementations—memory(简单版本)的实现
- C.Interface.And.Implementations—memory(复杂版本)的实现
- C.Interface.And.Implementations—memory(arena版)的实现
- C.Interface.And.Implementations—list(单链表)的实现
- C.Interface.And.Implementations—set的实现
- C.Interface.And.Implementations—dynamic arrays的实现
- C.Interface.And.Implementations—sequence的实现
- C.Interface.And.Implementations—ring的实现
- C.Interface.And.Implementations—bit vector的实现
- Implicit and Explicit Interface Implementation
- 显示接口成员实现(explicit interface member implementation)总结
- explicit 和Implicit 区别
- C.Interface.And.Implementations—table(key-value系统)的实现
- c#自定义类型的转换方式operator,以及implicit(隐式)和explicit (显示)声明的区别
- jquery 操作表单
- JAVA调用 ICTCLAS 分词接口
- Android应用程序窗口(Activity)的窗口对象(Window)的创建过程分析
- [Android学UI之三]实现新浪微博消息页面左右滑动页面方式二(二)
- sql参考资料汇总
- 显示实现和隐式实现接口的区别(Implicit and Explicit Interface Implementations)
- java中获得系统当前时间
- Oracle 11g 新特性 -- Invisible Indexes(不可见的索引) 说明
- 黑马程序员-java基础强化(一)
- IPhone中SQLite3的使用
- algorithm—for_each() (1)
- Linux Desktop Entry 文件深入解析
- Lucene的高亮器Highlighter
- 2012-11-24 - 11-25 11gR2 "Backup and Recovery User's Guide" page 425 - 442