int []符合IList <t>?</t>

时间:2013-02-17 08:57:45

标签: c#

在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 个答案:

答案 0 :(得分:6)

Array没有实现IList<T>,但T[]确实没有实现,这要归功于一些运行时魔术。数组有点奇怪,因为它应该是通用的,但是先于通用系统,因此使用专门的黑客。

答案 1 :(得分:5)

来自C#4规范的第12.1.2节:

  

一维数组T[]实现接口System.Collections.Generic.IList<T>及其基接口。因此,存在从T[]IList<T>及其基接口的隐式转换。

值得注意的是,如果你创建一个矩形数组一个具有非零的下限的一维数组,那些实现{{1} }。

在CLI中,实际上有两个术语: vector array 。向量是一个下限为零的一维集合,并且被JIT优化为heck和back。数组可以具有多个维度和不同的下限,并且不需要进行彻底的优化。

C#中的IList<T> 总是一个向量。你不能将一个CLI数组的对象强制转换为T[] - 最终会出现这样的异常:

T[]

答案 2 :(得分:1)

编辑:最初认为OP询问的是IList而不是IList<T>

...因为数组实现IList

public abstract class Array : ICloneable, IList, ICollection, IEnumerable, IStructuralComparable, IStructuralEquatable
//                                        ^^^^^

答案 3 :(得分:1)

稍微相关的说明:

T []实现IList&lt; T&gt;非常不幸。有时。请考虑以下代码:

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

真的不太好。

出于这个原因,在使用IList&lt; T&gt;之前需要仔细考虑。而不是T []。