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

时间:2022-09-25 11:59:09

When I press f12 on the ArrayList keyword to go to metadata generated from vs2008, I found that the generated class declaration as follows

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

public class ArrayList : IList, ICollection, IEnumerable, ICloneable

I know that the IList already inherits from ICollection and IEnumerable, so why does ArrayList redundantly inherit from these interfaces?

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

6 个解决方案

#1


OK, I've done some research. If you create the following hierarchy:

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

  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();
        }
    }

And compile it, then reference the DLL in a different solution, type Magic and Press F12, you will get the following:

然后编译它,然后在不同的解决方案中引用DLL,键入Magic并按F12,您将得到以下内容:

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

        public void DoIt();
        public void DoItMore();
    }

You will see that the interface hierarchy is flattened, or the compiler is adding the interfaces in? If you use reflector you get the same results too.

您将看到接口层次结构是扁平的,还是编译器正在添加接口?如果使用反射器,也会得到相同的结果。

Update: If you open the DLL in ILDASM, you will see it saying:

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

implements ...Two

implements ...One.

#2


The extra interfaces are shown because they are implied by IList. If you implement IList, you must also implement ICollection and IEnumerable.

显示额外的接口是因为它们是IList所暗示的。如果实现IList,则还必须实现ICollection和IEnumerable。

#3


I am just guessing, but I think in reality it only implements IList in code, but the documentation shows the rest of the interfaces as well to make it explicit to the programmer using the class.

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

#4


From MSDN....

If a class implements two interfaces that contain a member with the same signature, then implementing that member on the class will cause both interfaces to use that member as their implementation.

如果一个类实现了两个包含具有相同签名的成员的接口,那么在该类上实现该成员将导致两个接口都使用该成员作为其实现。

Explicit implementation is also used to resolve cases where two interfaces each declare different members of the same name such as a property and a method:

显式实现还用于解决两个接口各自声明同名的不同成员(例如属性和方法)的情况:

#5


Don't accept this as answer.

不要接受这个作为答案。

I am repeating what workmad3 said above.

我正在重复上面提到的workmad3。

By implementing it in ArrayList, it becomes easy for one to know - which interfaces ArrayList implements rather that going up to IList to find that it implements ICollection & IEnumerable.

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

That avoids the need for going back & forth the inheritance chain.

这避免了回传继承链的必要性。

EDIT: At the basic level, an interface implementing another interface cannot provide the implementation. The class derived (from IList) hence indirectly implements ICollection & IEnumerable as well. So, even if you write your own class implementing IList (and not add ICollection, IEnumerable in the declaration) - you will see that it will have to provide the implementation for ICollection & IEnumerable.

编辑:在基本级别,实现另一个接口的接口无法提供实现。派生的类(来自IList)因此也间接地实现ICollection和IEnumerable。因此,即使您编写自己的实现IList的类(并且不在声明中添加ICollection,IEnumerable) - 您将看到它必须提供ICollection和IEnumerable的实现。

And workmad3's reasoning makes sense.

而workmad3的推理是有道理的。

#6


My guess would be that the CLR does not support an interface that inherits from another interface.

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

C# however does support this construct but has to 'flatten' the inheritance tree to be CLR compliant.

但是,C#支持这种结构,但必须将继承树“展平”为符合CLR。

[Edit]

After taking advise from below quickly setup a VB.Net project:

从以下建议后快速设置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

Compiling results in the following (C#):

编译结果如下(C#):

public class Class1 : ITwo
{
    public Class1();
    public void DoIt();
    public void DoIt2();
}

This show that VB.Net does NOT flatten the interface hierarchy as opposed to C#. I have no clue as to why this would be.

这表明VB.Net不会扁平化接口层次结构而不是C#。我不清楚为什么会这样。

#1


OK, I've done some research. If you create the following hierarchy:

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

  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();
        }
    }

And compile it, then reference the DLL in a different solution, type Magic and Press F12, you will get the following:

然后编译它,然后在不同的解决方案中引用DLL,键入Magic并按F12,您将得到以下内容:

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

        public void DoIt();
        public void DoItMore();
    }

You will see that the interface hierarchy is flattened, or the compiler is adding the interfaces in? If you use reflector you get the same results too.

您将看到接口层次结构是扁平的,还是编译器正在添加接口?如果使用反射器,也会得到相同的结果。

Update: If you open the DLL in ILDASM, you will see it saying:

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

implements ...Two

implements ...One.

#2


The extra interfaces are shown because they are implied by IList. If you implement IList, you must also implement ICollection and IEnumerable.

显示额外的接口是因为它们是IList所暗示的。如果实现IList,则还必须实现ICollection和IEnumerable。

#3


I am just guessing, but I think in reality it only implements IList in code, but the documentation shows the rest of the interfaces as well to make it explicit to the programmer using the class.

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

#4


From MSDN....

If a class implements two interfaces that contain a member with the same signature, then implementing that member on the class will cause both interfaces to use that member as their implementation.

如果一个类实现了两个包含具有相同签名的成员的接口,那么在该类上实现该成员将导致两个接口都使用该成员作为其实现。

Explicit implementation is also used to resolve cases where two interfaces each declare different members of the same name such as a property and a method:

显式实现还用于解决两个接口各自声明同名的不同成员(例如属性和方法)的情况:

#5


Don't accept this as answer.

不要接受这个作为答案。

I am repeating what workmad3 said above.

我正在重复上面提到的workmad3。

By implementing it in ArrayList, it becomes easy for one to know - which interfaces ArrayList implements rather that going up to IList to find that it implements ICollection & IEnumerable.

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

That avoids the need for going back & forth the inheritance chain.

这避免了回传继承链的必要性。

EDIT: At the basic level, an interface implementing another interface cannot provide the implementation. The class derived (from IList) hence indirectly implements ICollection & IEnumerable as well. So, even if you write your own class implementing IList (and not add ICollection, IEnumerable in the declaration) - you will see that it will have to provide the implementation for ICollection & IEnumerable.

编辑:在基本级别,实现另一个接口的接口无法提供实现。派生的类(来自IList)因此也间接地实现ICollection和IEnumerable。因此,即使您编写自己的实现IList的类(并且不在声明中添加ICollection,IEnumerable) - 您将看到它必须提供ICollection和IEnumerable的实现。

And workmad3's reasoning makes sense.

而workmad3的推理是有道理的。

#6


My guess would be that the CLR does not support an interface that inherits from another interface.

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

C# however does support this construct but has to 'flatten' the inheritance tree to be CLR compliant.

但是,C#支持这种结构,但必须将继承树“展平”为符合CLR。

[Edit]

After taking advise from below quickly setup a VB.Net project:

从以下建议后快速设置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

Compiling results in the following (C#):

编译结果如下(C#):

public class Class1 : ITwo
{
    public Class1();
    public void DoIt();
    public void DoIt2();
}

This show that VB.Net does NOT flatten the interface hierarchy as opposed to C#. I have no clue as to why this would be.

这表明VB.Net不会扁平化接口层次结构而不是C#。我不清楚为什么会这样。