接口一个被我忽略的地方--接口重定向技术
習慣于用IDE生成接口方法了,右鍵點擊"Implement Interface",生成所有的接口方法聲明,還帶個Region多方便啊.
今天看<<CLR Vir C#>>時才了解到自己是知其然不知其所有然啊.
?實現(xiàn)接口方法很簡單,新手估計也都會,但怎么理解這個過程,不見得所有人都知道
class?Base?:?IDisposable
{?
????IDisposable?Members#region?IDisposable?Members
????public?void?Dispose()
????{
????????Console.WriteLine("Base's?Dispose");
????}
????#endregion
}
首先我們可以簡單的認為Base類里有個Dispose()的方法.這個方法跟是不是IDisposable的成員,先理解為沒有關(guān)系.當編譯這個類的時候,編譯器發(fā)現(xiàn)它實現(xiàn)了IDisposable接口,于是查找有沒有跟其成員IDisposable.Dispose()同名,參數(shù)和返回類型完全匹配,并且是public的,如果找到就在IVMap里指向這個方法的入口(我猜的,這地方具體見http://www.microsoft.com/china/MSDN/library/netFramework/netframework/JITCompiler.mspx?mfr=true)如果沒有就出個編譯錯誤.
如果找到的方法前面有virtual關(guān)鍵字,編譯器仍然認為是匹配的.如何沒有virtual關(guān)鍵字,編譯器默認的還會為其加上sealed.那么其子類是無法override的.如何想要override父類的Dispose()方法,最好是在Base中定義Dispose()時使用virtual.當然如果我們沒有權(quán)利改寫B(tài)ase類,我們可以讓其子類同樣繼承自IDisposable,然后改寫方法.這點已經(jīng)有很多人談?wù)撨^了,估計大家基本都明白.不了解的可以gongle it!
Derived
class?Derived?:?Base,?IDisposable
{
????public?void?Dispose()
????{
????????Console.WriteLine("Derived's?Dispose");
????}
}
現(xiàn)在問題來了,我們是真的改寫了父類的Dispose()方法嗎?
測試一下:
Base c = new Derived();
c.Dispose();
結(jié)果你可以發(fā)現(xiàn)輸出的是: Base's Dispose.當時我覺得很奇怪,后來靜下來想想原來可以這么理解.
就如我開始理解接口實現(xiàn)過程一樣,對于上面的代碼我們可以直接忽略接口的存在,等效如下
class?Base?
{?
????public?void?Dispose()
????{
????????Console.WriteLine("Base's?Dispose");
????}
}
class?Derived?:?Base?
{
????public?void?Dispose()
????{
????????Console.WriteLine("Derived's?Dispose");
????}
}
這樣大家應該都知道為什么輸出是Base's Dispose,如果不知道可以去查看 "今天你多態(tài)了嗎"一文,說的很詳細了.
回過來看我們剛才的代碼,編譯的時候有個警告:?? 'Program.Derived.Dispose()' hides inherited member 'Program.Base.Dispose()'. Use the new keyword if hiding was intended.?
是不是把Dispose()看成只是類的方法更容易理解呢.只是通過接口調(diào)用的時候指向了這個方法的入口而已.
我以為如下實現(xiàn)Derived類會更好些,不會讓你產(chǎn)生誤解,以為Derived? override了Base類的Dispose()方法
顯示實現(xiàn)接口class?Derived?:?Base,?IDisposable
{
????void?IDisposable.Dispose()
????{
????????Console.WriteLine("Derived's?Dispose");
????}
}
對于如下代碼不要期待能輸出Derived's Dispose結(jié)果.當然如果CallDispose()傳入的參數(shù)類型是IDisposable,就當我沒說過
static void Main(string[] args)
{
??? Derived c = new Derived();
??? CallDispose(c);
}
private static void CallDispose(Base b)
{
??? b.Dispose();
}
要不然你得這樣
private static void CallDispose(Base b)
{
??? ((IDispose))b.Dispose();
}
但是你會覺得很別扭.當然 CallDispose(Base b)定義成這樣本身就是個不好的設(shè)計.
具體大家可以看看<<CLR Vir C#>>14章,我想對于你理解接口實現(xiàn)的整個過程會有莫大的幫助
轉(zhuǎn)載于:https://www.cnblogs.com/anders06/archive/2007/06/12/780719.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的接口一个被我忽略的地方--接口重定向技术的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CSS样式表的规划与组织
- 下一篇: 蘋果的秘密武器