Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么C#(如ArrayList)中的集合类从多个接口继承,而其中一个接口从其余接口继承?_C#_Inheritance_Interface_Arraylist - Fatal编程技术网

为什么C#(如ArrayList)中的集合类从多个接口继承,而其中一个接口从其余接口继承?

为什么C#(如ArrayList)中的集合类从多个接口继承,而其中一个接口从其余接口继承?,c#,inheritance,interface,arraylist,C#,Inheritance,Interface,Arraylist,当我在ArrayList关键字上按f12键转到从vs2008生成的元数据时,我发现生成的类声明如下 public class ArrayList : IList, ICollection, IEnumerable, ICloneable 我知道IList已经从ICollection和IEnumerable继承,那么为什么ArrayList会冗余地从这些接口继承呢?显示额外的接口是因为IList隐含了这些接口。如果实现IList,还必须实现ICollection和IEnumerable。我只是猜

当我在ArrayList关键字上按f12键转到从vs2008生成的元数据时,我发现生成的类声明如下

public class ArrayList : IList, ICollection, IEnumerable, ICloneable

我知道IList已经从ICollection和IEnumerable继承,那么为什么ArrayList会冗余地从这些接口继承呢?

显示额外的接口是因为IList隐含了这些接口。如果实现IList,还必须实现ICollection和IEnumerable。

我只是猜测,但我认为实际上它只在代码中实现IList,但文档中还显示了其余接口,以使其对使用该类的程序员显式。

From

如果一个类实现了两个接口 包含具有相同 签名,然后执行 类中的成员将导致 将该成员用作其成员的接口 实施

还使用显式实现 解决两个接口 每个国家都宣布了不同的国家成员 相同的名称,例如属性和 方法:


好的,我做了一些调查。如果创建以下层次结构:

  public interface One
    {
        void DoIt();
    }

    public interface Two : One
    {
        void DoItMore();
    }

    public class Magic : Two
    { 
        public void DoItMore()
        {
            throw new NotImplementedException();
        }

        public void DoIt()
        {
            throw new NotImplementedException();
        }
    }
并编译它,然后在不同的解决方案中引用DLL,键入Magic并按F12,您将得到以下结果:

 public class Magic : Two, One
    {
        public Magic();

        public void DoIt();
        public void DoItMore();
    }
您将看到接口层次结构被展平,或者编译器正在中添加接口?如果你使用反射器,你也会得到同样的结果

更新:如果在ILDASM中打开DLL,您将看到它说:

两个


实现…一个。

不要接受这个答案

我重复上面workmad3所说的

通过在ArrayList中实现它,人们可以很容易地知道ArrayList实现了哪些接口,而不是在IList中发现它实现了ICollection&IEnumerable

这避免了在继承链中来回移动的需要

编辑:在基本级别,实现另一个接口的接口不能提供实现。因此(从IList派生的)类间接地实现了ICollection和IEnumerable。因此,即使您编写自己的类来实现IList(而不是在声明中添加ICollection、IEnumerable),您也会看到它必须为ICollection和IEnumerable提供实现


workmad3的推理是有道理的。

我猜CLR不支持从另一个接口继承的接口

然而,C#确实支持这种构造,但必须“展平”继承树才能兼容CLR

[编辑]

从下面获取建议后,快速设置VB.Net项目:

Public Interface IOne
    Sub DoIt()
End Interface

Public Interface ITwo
    Inherits IOne
    Sub DoIt2()
End Interface

Public Class Class1
    Implements ITwo

    Public Sub DoIt() Implements IOne.DoIt
        Throw New NotImplementedException()
    End Sub

    Public Sub DoIt2() Implements ITwo.DoIt2
        Throw New NotImplementedException()
    End Sub
End Class
编译结果如下(C#):


这表明VB.Net与C#相反,并没有扁平化接口层次结构。我不知道为什么会这样。

好的,这意味着它是从vs生成的,而不是ArrayList的真正声明?是的。如果使用Reflector查看基本类型,则可以看到它只显式实现IList和IClonable。微软的公共Rotor源代码也是如此:我想VS可能会使方法实现变得平坦。也就是说,由于IList实现了ICollection,ArrayList提供了ICollection方法的实现。但文档中已经有了。我的问题是,为什么ArrayList继承ICollection和IEnumerable,只要IList继承ICollection和IEnumerable???+1这是一个很好的问题。我同意。在reflector中,ArrayList被定义为公共类ArrayList:IList、ICollection、IEnumerable、ICloneable我做了一些研究,并添加了一个带有代码示例的答案为什么重要?包含上面提到的每一个接口不是让事情变得更清楚吗?@mP-这并不重要,但这仍然是一个有趣的问题!即使它确实显式地实现了所有接口,接口的显式性还是很好的,因为您可以通过查看这些接口来告诉您需要实现的一切,而不是通过挖掘接口及其基础等。我可以理解您的观点,但我怀疑这是否是一件好事。我想有点多余也无妨,但我从来没见过自己用这种方式编写代码,这仍然回避了一个问题:MS在哪里记录了他们这样做的意图?我想,因为知道这一点很方便。不是每个人都知道IList继承自ICollection和IEnumerable(或者用另一个层次结构替换这个句子)。-1:与其在三周后猜测,不如在VB.NET中尝试一下,在回答之前找出答案。当然不着急。
public class Class1 : ITwo
{
    public Class1();
    public void DoIt();
    public void DoIt2();
}