日期:2014-05-18  浏览次数:20840 次

问一个巨简单的问题,可是我怎么也没想懂。。。我们常看到书上这么说...
我们常看到书上这么说 , msdn里也这么写
ICollection 继承于 IEnumerable
IList 继承于 ICollection 和 IEnumerable
IDictionary 继承于 ICollection 和 IEnumerable
ArrayList 实现了 IEnumerable,ICollection ,IList 接口之类的话

可是,既然
ICollection 继承于 IEnumerable
那直接说
IList 继承于 ICollection不就可以了吗,为什么还要说
IList 继承于 ICollection 和 IEnumerable
同理,直接说,
ArrayList 实现了IList 不就可以了吗?

------解决方案--------------------
不是一回事...

这个问题可不简单啊...它们是为了显式实现接口...

--------------MSDN--------------------
当接口成员由类显式实现时,只能通过使用对接口的引用来访问该成员。这将导致隐藏接口成员。显式实现接口成员的常见原因不仅是为了符合接口的协定,而且也是为了以某种方式改进它(例如,提供应用来代替接口的弱类型方法的强类型方法)。显式实现接口成员的另一个常见原因是存在不应由开发人员调用显式接口成员的时候。例如,GetObjectData 成员是最常显式实现的,因为它由序列化基础结构调用而不用于从代码调用。

下列设计准则有助于确保您的库设计仅在需要时使用显式接口实现。

如果没有充分理由,应避免显式实现接口成员。
要理解显式实现需要具备很高深的专业知识。例如,很多开发人员不知道显式实现的成员是可以公共调用的,即使其签名是私有的也一样。由于这个原因,显式实现的成员不显示在公共可见的成员列表中。显式实现成员还会导致对值类型的不必要装箱。

如果成员只应通过接口调用,则考虑显式实现接口成员。
这主要包括支持.NET Framework基础结构(如数据绑定或序列化)的成员。例如,IsReadOnly属性只应由数据绑定基础结构通过使用对ICollection接口的引用来访问。由于满足此准则,List类显式实现该属性。

考虑显式实现接口成员以模拟变体(即,更改重写成员中的参数或返回类型)。
为了提供接口成员的强类型版本,通常会这么做。 

考虑显式实现接口成员以隐藏一个成员并添加一个具有更好名称的等效成员。
这样可以有效地重命名成员。例如,Stream显式实现Dispose并在相应的位置提供Close方法。

不要将显式成员用作安全边界。
显式实现成员不提供任何安全性。通过使用对接口的引用,这些成员都是可以公共调用的。

如果显式实现的成员的功能意在由派生类特殊化,则一定要提供具有相同功能的受保护虚拟成员。
不能重写显式实现的成员。如果在派生类中重新定义成员,则派生类不能调用基类实现。应通过使用与显式接口成员相同的名称或将Core附加到接口成员名称来命名受保护成员。
--------------MSDN--------------------
------解决方案--------------------
IList 继承于 ICollection不就可以了吗,为什么还要说 
IList 继承于 ICollection 和 IEnumerable 


IList 继承于 ICollection 和 IEnumerable ,这样明确表示无论 ICollection 和 IEnumerable 的定义如何,IList 都实现了 ICollection 和 IEnumerable ,这是明确定义的。


IList 继承于 ICollection , 那么 IList 只能明确定义了实现 ICollection,这样就不表示 IList 一定实现了 IEnumerable ,因为 ICollection 可能不一定实现了 IEnumerable 。


但不是如 vrhero 所说的,是为了显示实现接口。

IList 是接口,显示实现接口是对于类而言的,对于接口没有“显示实现接口”这一说的,对于类 ArrayList,你可以说是为了显示实现接口,
但也不是因为这样,因为即使是 ArrayList :IList 也可以显示实现 IList,ICollection , IEnumerable 的成员,对于“为了显示实现接口”,
“ArrayList :IList ”声明和“ArrayList :IList ,ICollection , IEnumerable ”是没有区别的,例如下列代码:

C# code

namespace InterfaceTestA
{
    interface InterA
    {
        int GetValue();
    }

    interface InterB : InterA
    {
        new int GetValue();
    }

    interface InterC : InterB
    {
        new int GetValue();
    }

    class ClassA : InterC
    {
        public int GetValue()
        {
            return 1;
        }

        #region InterC 成员

        int InterC.GetValue()
        {
            throw new Exception("The method or operation is not implemented.");
        }

        #endregion

        #region InterB 成员

        int InterB.GetValue()
        {
            throw new Exception("The method or operation is not implemented.");
        }

        #endregion

        #region InterA 成员

        int InterA.GetValue()
        {
            throw new Exception("The method or operation is not implemented.");
        }

        #endregion
    }

    class Program
    {
        static void Main(string[] args)
        {
        }
    }
}