新しい.NET 3.5プログラマーとして、私はLINQを学び始めましたが、これまで気付かなかった非常に基本的なものを見つけました。
この本は、すべての配列がIEnumerable<T>
を実装していると主張しています(明らかに、そうでなければ、LINQを配列上のオブジェクトに使用できませんでした...)。これを見たとき、私はそれについて本当に考えたことはないと自分自身に考え、すべての配列が実装している他のことを自問しました-それで、オブジェクトブラウザを使用してSystem.Array
を調べました(それは、 CLR)そして、驚いたことに、IEnumerable<T>
を実装していません。
だから私の質問は次のとおりです。定義はどこですか?つまり、すべての配列が実装しているインターフェイスを正確に知るにはどうすればよいですか?
documentation (emphasis mine)から:
[...] Arrayクラスは
System.Collections.Generic.IList<T>
、System.Collections.Generic.ICollection<T>
、およびSystem.Collections.Generic.IEnumerable<T>
汎用インターフェース。 実装は実行時に配列に提供されるため、ドキュメント作成ツールには表示されません。
EDIT:Jb Evainがコメントで指摘しているように、ベクトル(1次元配列)のみが汎用インターフェイスを実装しています。 why多次元配列がジェネリックインターフェイスを実装しないことに関しては、非ジェネリックインターフェイスを実装しているため、よくわかりません(以下のクラス宣言を参照)。
System.Array
クラス(つまりevery配列)は、これらの非汎用インターフェイスも実装します。
public abstract class Array : ICloneable, IList, ICollection, IEnumerable, IStructuralComparable, IStructuralEquatable
小さいコードスニペットを使用して、質問に対する答えを経験的に見つけることができます。
foreach (var type in (new int[0]).GetType().GetInterfaces())
Console.WriteLine(type);
上記のスニペットを実行すると、次の出力が得られます(.NET 4.0
):
System.ICloneable
System.Collections.IList
System.Collections.ICollection
System.Collections.IEnumerable
System.Collections.IStructuralComparable
System.Collections.IStructuralEquatable
System.Collections.Generic.IList`1[System.Int32]
System.Collections.Generic.ICollection`1[System.Int32]
System.Collections.Generic.IEnumerable`1[System.Int32]
(`1
は<T>
を意味します)
.NET 4.5
(.NET Standard 1.0
以降)の後に、2つの追加のインターフェイスがあります。
System.Collections.Generic.IReadOnlyList`1[System.Int32]
System.Collections.Generic.IReadOnlyCollection`1[System.Int32]
。NET 4.5からは、配列もインターフェイスを実装します System.Collections.Generic.IReadOnlyList<T>
および System.Collections.Generic.IReadOnlyCollection<T>
。
したがって、.NET 4.5を使用する場合、配列によって実装されるインターフェイスの完全なリストは( Hosam Aly's answer に示された方法を使用して取得されます):
System.Collections.IList
System.Collections.ICollection
System.Collections.IEnumerable
System.Collections.IStructuralComparable
System.Collections.IStructuralEquatable
System.Collections.Generic.IList`1[System.Int32]
System.Collections.Generic.ICollection`1[System.Int32]
System.Collections.Generic.IEnumerable`1[System.Int32]
System.Collections.Generic.IReadOnlyList`1[System.Int32]
System.Collections.Generic.IReadOnlyCollection`1[System.Int32]
奇妙なことに、これら2つのインターフェイスに言及するために MSDNのドキュメント を更新するのを忘れていたようです。
配列インターフェースに注意深く、それらを実装するかもしれませんが、実際には実際にはこれを行いません...次のコードを見てみましょう:
var x = new int[] { 1, 2, 3, 4, 5 };
var y = x as IList<int>;
Console.WriteLine("The IList:" + string.Join(",", y));
try
{
y.RemoveAt(1);
}
catch (Exception e)
{
Console.WriteLine(e);
}
Console.WriteLine(string.Join(",", y));
次の出力が生成されます。 result
したがって、解析は機能しますが、すべてがサポートされているわけではなく、固定長のコレクションの観点からは正しいですが、リストであると本当に信じている場合は非常に間違っています。 SOLID :(。
高速テストの場合 this が役立ちます。
配列のSZArrayHelper
ネストクラスでIList<T>, ICollection<T>, IEnumerable<T>
の実装を見つけました。
しかし、私はあなたに警告する必要があります-そこで、あなたはより多くの質問を見つけるでしょう...
その後、私は1つだけを得ました-there_is_no_array;)