C#对接口成员访问分析

开发 后端
这里介绍C#对接口成员访问,如果底层成员的命名与继承而来的高层成员一致,那么底层成员将覆盖同名的高层成员。

在向大家详细介绍C#对接口成员访问之前,首先让大家了解下C#对接口方法的调用,然后全面介绍C#对接口成员访问。

C#对接口成员访问

C#对接口方法的调用和采用索引指示器访问的规则与类中的情况也是相同的。如果底层成员的命名与继承而来的高层成员一致,那么底层成员将覆盖同名的高层成员。但由于接口支持多继承,在多继承中,如果两个父接口含有同名的成员,这就产生了二义性(这也正是C#中取消了类的多继承机制的原因之一),这时需要进行显式的定义:

  1. using System ;  
  2. interface ISequence {  
  3. int Count { get; set; }  
  4. }  
  5. interface IRing {  
  6. void Count(int i) ;  
  7. }  
  8. interface IRingSequence: ISequence, IRing { }  
  9. class CTest {  
  10. void Test(IRingSequence rs) {  
  11. //rs.Count(1) ; 错误, Count 有二义性  
  12. //rs.Count = 1; 错误, Count 有二义性  
  13. ((ISequence)rs).Count = 1; // 正确  
  14. ((IRing)rs).Count(1) ; // 正确调用IRing.Count  
  15. }  

上面的例子中,前两条语句rs .Count(1)和rs .Count = 1会产生二义性,从而导致编译时错误,因此必须显式地给rs 指派父接口类型,这种指派在运行时不会带来额外的开销。

再看下面的例子:

  1. using System ;  
  2. interface IInteger {  
  3. void Add(int i) ;  
  4. }  
  5. interface IDouble {  
  6. void Add(double d) ;  
  7. }  
  8. interface INumber: IInteger, IDouble {}  
  9. class CMyTest {  
  10. void Test(INumber Num) {  
  11.  
  12. // Num.Add(1) ; 错误  
  13. Num.Add(1.0) ; // 正确  
  14. ((IInteger)n).Add(1) ; // 正确  
  15. ((IDouble)n).Add(1) ; // 正确  
  16. }  

调用Num.Add(1) 会导致二义性,因为候选的重载方法的参数类型均适用。但是,调用Num.Add(1.0) 是允许的,因为1.0 是浮点数参数类型与方法IInteger.Add()的参数类型不一致,这时只有IDouble.Add 才是适用的。不过只要加入了显式的指派,就决不会产生二义性。

接口的多重继承的问题也会带来C#对接口成员访问上的问题。例如:

  1. interface IBase {  
  2. void FWay(int i) ;  
  3. }  
  4. interface ILeft: IBase {  
  5. new void FWay (int i) ;  
  6. }  
  7. interface IRight: IBase  
  8. { void G( ) ; }  
  9. interface IDerived: ILeft, IRight { }  
  10. class CTest {  
  11. void Test(IDerived d) {  
  12. d. FWay (1) ; // 调用ILeft. FWay  
  13. ((IBase)d). FWay (1) ; // 调用IBase. FWay  
  14. ((ILeft)d). FWay (1) ; // 调用ILeft. FWay  
  15. ((IRight)d). FWay (1) ; // 调用IBase. FWay  
  16. }  

上例中,方法IBase.FWay在派生的接口ILeft中被Ileft的成员方法FWay覆盖了。所以对d. FWay (1)的调用实际上调用了。虽然从IBase-> IRight-> IDerived这条继承路径上来看,ILeft.FWay方法是没有被覆盖的。我们只要记住这一点:一旦成员被覆盖以后,所有对其的访问都被覆盖以后的成员"拦截"了。

【编辑推荐】

  1. C# this关键字详解
  2. C#调用析构方法详解
  3. C#释放托管资源简单描述
  4. C#单路代理简单分析
  5. C#文法产生式概述
责任编辑:佚名 来源: 博客园
相关推荐

2009-08-03 18:26:18

C#定义接口成员

2009-08-24 10:06:31

C#接口成员

2009-08-31 17:02:28

C#接口编程

2010-07-26 09:20:48

C#

2009-08-18 10:30:30

C#枚举

2009-08-06 16:01:30

C#接口成员

2009-08-24 11:02:52

C#接口映射

2009-08-24 09:55:26

C#接口转换

2009-08-25 10:57:09

C#接口

2009-08-24 11:20:03

C#接口

2009-08-25 10:44:08

C#接口定义接口

2009-08-31 13:18:09

C# IWebMess

2009-08-24 10:31:37

C#接口继承

2009-08-31 15:55:17

C#实现Strateg

2009-08-03 18:08:39

C# ICloneab

2009-08-14 17:58:05

C#接口方法

2009-08-25 17:55:52

C#实现Strateg

2009-08-10 10:04:25

C#抽象类C#接口

2009-08-28 14:09:19

C#静态类

2009-07-31 16:06:50

成员函数构造函数C#
点赞
收藏

51CTO技术栈公众号