0

stackoverflowに関する別の質問で、誰かが配列の拡張メソッドを作成することを提案しましたが、拡張メソッドでthis IList<T>インターフェイスを使用しました。私はそれが配列であるべきだとコメントしましたが、彼は断りました。私はそれをテストしました、そしてもちろん、彼は正しいです... :)

拡張方法:

public static void Fill<T>(this IList<T> array, T value)
{
    for(var i = 0; i < array.Count; i++) 
    {
        array[i] = value;
    }
}

テストコード:

[Test] 
public void Stackoverflow()
{
    int[] arr = new int[] { 1,2,3,4};
    arr.Fill(2);
    Assert.AreEqual(2, arr[0]);
    Assert.AreEqual(2, arr[1]);
    Assert.AreEqual(2, arr[2]);
    Assert.AreEqual(2, arr[3]);
}

arrayではありませんIList<T>。なぜこれがコンパイルされるのですか?言うまでもなく、合格?

4

4 に答える 4

6

Arrayは実装していませんIList<T>T[]、ランタイムマジックのおかげで実装しています。配列は汎用的であるはずなので少し奇妙ですが、汎用システムよりも前のものであるため、特殊なハックを使用します。

于 2013-02-17T09:00:05.300 に答える
5

C# 4 仕様のセクション 12.1.2 から:

1 次元配列は、インターフェイスとその基本インターフェイスをT[]実装します。したがって、 toおよびその基本インターフェイスSystem.Collections.Generic.IList<T>からの暗黙的な変換があります。T[]IList<T>

ゼロ以外の下限を持つ矩形配列または1 次元配列を作成する場合、それらは を実装しないIList<T>ことに注意してください。

CLI には、実際にはvectorarrayの 2 つの用語があります。ベクターは、下限がゼロの 1 次元のコレクションであり、JIT によってヘック アンド バックするように最適化されています。配列は複数の次元と異なる下限を持つことができ、完全な最適化の対象にはなりません。

C#の AT[]常にベクトルです。CLI 配列であるオブジェクトをキャストすることはできませんT[]。次のような例外が発生します。

Unhandled Exception: System.InvalidCastException: Unable to cast object of type
'System.String[*]' to type 'System.String[]'.
于 2013-02-17T09:02:14.580 に答える
1

編集:元々、OPは質問していて、質問しIListていないと思っていIList<T>ました。

...配列が実装するためIList

public abstract class Array : ICloneable, IList, ICollection, IEnumerable, IStructuralComparable, IStructuralEquatable
//                                        ^^^^^
于 2013-02-17T08:58:59.327 に答える
1

少し関連するメモについて:

T[] が IList<T> を実装することがあるのは非常に残念です。次のコードを検討してください。

int[] array = new int[10];
IList<int> list = array; // Compiles
list.Add(1);             // Runtime error. Ew!

あまり良くありません。

このため、T[] の代わりに IList<T> を使用する前に、慎重に検討する必要があります。

于 2013-02-17T09:46:58.893 に答える