C#對(duì)接口成員訪問(wèn)分析
在向大家詳細(xì)介紹C#對(duì)接口成員訪問(wèn)之前,首先讓大家了解下C#對(duì)接口方法的調(diào)用,然后全面介紹C#對(duì)接口成員訪問(wèn)。
C#對(duì)接口成員訪問(wèn)
C#對(duì)接口方法的調(diào)用和采用索引指示器訪問(wèn)的規(guī)則與類中的情況也是相同的。如果底層成員的命名與繼承而來(lái)的高層成員一致,那么底層成員將覆蓋同名的高層成員。但由于接口支持多繼承,在多繼承中,如果兩個(gè)父接口含有同名的成員,這就產(chǎn)生了二義性(這也正是C#中取消了類的多繼承機(jī)制的原因之一),這時(shí)需要進(jìn)行顯式的定義:
- using System ;
- interface ISequence {
- int Count { get; set; }
- }
- interface IRing {
- void Count(int i) ;
- }
- interface IRingSequence: ISequence, IRing { }
- class CTest {
- void Test(IRingSequence rs) {
- //rs.Count(1) ; 錯(cuò)誤, Count 有二義性
- //rs.Count = 1; 錯(cuò)誤, Count 有二義性
- ((ISequence)rs).Count = 1; // 正確
- ((IRing)rs).Count(1) ; // 正確調(diào)用IRing.Count
- }
- }
上面的例子中,前兩條語(yǔ)句rs .Count(1)和rs .Count = 1會(huì)產(chǎn)生二義性,從而導(dǎo)致編譯時(shí)錯(cuò)誤,因此必須顯式地給rs 指派父接口類型,這種指派在運(yùn)行時(shí)不會(huì)帶來(lái)額外的開銷。
再看下面的例子:
- using System ;
- interface IInteger {
- void Add(int i) ;
- }
- interface IDouble {
- void Add(double d) ;
- }
- interface INumber: IInteger, IDouble {}
- class CMyTest {
- void Test(INumber Num) {
- // Num.Add(1) ; 錯(cuò)誤
- Num.Add(1.0) ; // 正確
- ((IInteger)n).Add(1) ; // 正確
- ((IDouble)n).Add(1) ; // 正確
- }
- }
調(diào)用Num.Add(1) 會(huì)導(dǎo)致二義性,因?yàn)楹蜻x的重載方法的參數(shù)類型均適用。但是,調(diào)用Num.Add(1.0) 是允許的,因?yàn)?.0 是浮點(diǎn)數(shù)參數(shù)類型與方法IInteger.Add()的參數(shù)類型不一致,這時(shí)只有IDouble.Add 才是適用的。不過(guò)只要加入了顯式的指派,就決不會(huì)產(chǎn)生二義性。
接口的多重繼承的問(wèn)題也會(huì)帶來(lái)C#對(duì)接口成員訪問(wèn)上的問(wèn)題。例如:
- interface IBase {
- void FWay(int i) ;
- }
- interface ILeft: IBase {
- new void FWay (int i) ;
- }
- interface IRight: IBase
- { void G( ) ; }
- interface IDerived: ILeft, IRight { }
- class CTest {
- void Test(IDerived d) {
- d. FWay (1) ; // 調(diào)用ILeft. FWay
- ((IBase)d). FWay (1) ; // 調(diào)用IBase. FWay
- ((ILeft)d). FWay (1) ; // 調(diào)用ILeft. FWay
- ((IRight)d). FWay (1) ; // 調(diào)用IBase. FWay
- }
- }
上例中,方法IBase.FWay在派生的接口ILeft中被Ileft的成員方法FWay覆蓋了。所以對(duì)d. FWay (1)的調(diào)用實(shí)際上調(diào)用了。雖然從IBase-> IRight-> IDerived這條繼承路徑上來(lái)看,ILeft.FWay方法是沒有被覆蓋的。我們只要記住這一點(diǎn):一旦成員被覆蓋以后,所有對(duì)其的訪問(wèn)都被覆蓋以后的成員"攔截"了。
【編輯推薦】