某天,小新問我這樣一個問題:
類System.Collections.CollectionBase是從IList、ICollection繼承而來,IList是從ICollection和IEnumerable繼承而來,那CollectionBase為什麼還要從ICollection繼承呢?
我們先來看看這些類和接口在MSDN文檔中的聲明:
public interface IEnumerable
public interface ICollection : IEnumerable
public interface IList : ICollection, IEnumerable
public abstract class CollectionBase : IList, ICollection, IEnumerable
根據接口繼承的規則,我們知道CollectionBase只需要聲明實現IList,就必須同時實現ICollection,也就必須實現IEnumerable,那麼,我們為什麼還要明確地把所有的這些接口都寫下來呢?
換句話說,下面兩種聲明沒有實質的區別:
// Code #1
public interface IEnumerable
public interface ICollection : IEnumerable
public interface IList : ICollection, IEnumerable
public class ArrayList : IList, ICollection, IEnumerable, ICloneable
// Code #2
public interface IEnumerable
public interface ICollection : IEnumerable
public interface IList : ICollection
public class ArrayList : IList, ICloneable
那為何MSDN要使用上面那種呢?我和小新討論後,一致認為這樣做僅僅為了提高代碼的可讀性。為了驗證我們的想法,我分別發郵件給Eric Gunnerson(Eric是C# Compiler Team的成員)和Kit George(Kit是BCL Team的成員)詢問這個問題,他們的回信如下:
Allen,
I think that readability would be the primary reason people would do this.
Eric
Allen, what you’re seeing is simply a doc thing. ArrayList actually only implements IList directly, but we decided in V1.0 of the docs, to highlight the interface hIErarchy so you didn’t have to wonder ‘what does IList implement’, you get to see it there on the type.
There is no benefit to ACTUALLY doing this. Try this code, and you’ll see it compiles:
using System;
using System.IO;
public class Test : IBob2
{
void IBob.M() {}
}
interface IBob
{
void M();
}
interface IBob2 : IBob {}
Regards,
Kit
今天,我查看微軟的Rotor源代碼,發現ArrayList的聲明的確是Code #1的做法,不過Mono(ver. 1.1.2 Development Version)就采用了Code #2的做法。
所以,以後如果你再碰到到這樣的情況,你可以輕松的笑一聲:“這樣做是為了提高代碼的可讀性的!”