C#のコレクションクラス(ArrayListなど)が、これらのインターフェイスの1つが残りのインターフェイスを継承する場合、複数のインターフェイスを継承するのはなぜですか?

StackOverflow https://stackoverflow.com/questions/1023375

質問

ArrayListキーワードでf12を押してvs2008から生成されたメタデータに移動すると、生成されたクラス宣言は次のようになりました

public class ArrayList : IList, ICollection, IEnumerable, ICloneable

IListはすでにICollectionとIEnumerableを継承しているので、ArrayListがこれらのインターフェイスを冗長に継承するのはなぜですか?

役に立ちましたか?

解決

OK、私はいくつかの研究をしました。次の階層を作成する場合:

  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を開くと、次のように表示されます。

implements ... 2

implements ... One。

他のヒント

追加のインターフェイスは、IListに含まれているため表示されます。 IListを実装する場合は、ICollectionとIEnumerableも実装する必要があります。

推測しているだけですが、実際にはコードでIListのみを実装していると思いますが、ドキュメントでは、クラスを使用するプログラマーに明示的にするために、残りのインターフェイスも示しています。

MSDN から...

  

クラスが2つのインターフェイスを実装する場合   同じメンバーを含む   署名、それを実装   クラスのメンバーは両方を引き起こします   そのメンバーを使用するインターフェース   実装。

     

明示的な実装も使用されます   2つのインターフェイスがある場合の解決   それぞれの異なるメンバーを宣言する   プロパティや   メソッド:

これを回答として受け入れないでください。

上記のworkmad3の発言を繰り返しています。

ArrayListに実装することにより、IListに移動してICollection&を実装していることを見つけるのではなく、ArrayListが実装するインターフェイスを知ることが容易になります。 IEnumerable。

これにより、元に戻る必要がなくなります。継承チェーンの前。

EDIT:基本レベルでは、別のインターフェイスを実装するインターフェイスは実装を提供できません。 (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#):

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

これは、VB.NetがC#とは対照的にインターフェース階層を平坦化しないしないことを示しています。なぜそうなるのかはわかりません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top