为什么C#多维数组没有实现IEnumerable <t>?</t>

时间:2008-11-08 19:20:44

标签: c# .net arrays multidimensional-array

我刚刚注意到C#中的多维数组没有实现IEnumerable<T>,而它确实实现了IEnumerable。对于一维数组,IEnumerable<T>IEnumerable都已实现。

为什么会出现这种差异?如果多维数组是IEnumerable,那么它肯定还应该实现通用版本吗?我注意到了这一点,因为我试图在多维数组上使用扩展方法,除非你使用Cast<T>或类似的,否则会失败;所以我绝对可以看到让多维数组实现IEnumerable<T>的论据。

为了在代码中澄清我的问题,我希望以下代码可以打印true四次,而实际上会打印truefalsetrue,{{ 1}}:

true

6 个答案:

答案 0 :(得分:45)

CLR有两种不同的数组:向量,它们保证是一维的下限为0,更通用的数组可以有非零边界和一个等级比0。

从CLI规范的第8.9.1节开始:

  

此外,创建的矢量用   元素类型T,实现   接口   System.Collections.Generic.IList<U>   (§8.7),其中U:= T。

我不得不说这对我来说似乎很奇怪。鉴于它已经实现IEnumerable,我不明白为什么它不应该实现IEnumerable<T>。实现IList<T>并没有多大意义,但简单的通用接口就没问题了。

如果你想要这个,你可以调用Cast<T>(如果你使用的是.NET 3.5)或编写自己的方法来迭代数组。为了避免强制转换,你必须编写自己的方法,找到每个维度的下限/上限,并以这种方式获取东西。不是非常愉快。

答案 1 :(得分:14)

有一种解决方法:您可以将任何多维数组转换为IEnumerable

public static class ArrayExtensions
{
    public static IEnumerable<T> ToEnumerable<T>(this Array target)
    {
        foreach (var item in target)
            yield return (T)item;
    }
}

答案 2 :(得分:4)

多维数组是 not 数组,用于继承层次结构。它们是完全独立的类型。此外,由于两个可能的原因,此类型没有得到框架的良好支持:

  • 这不是那么有用。多维数组唯一真正的用途是矩阵。对于几乎任何其他数据,其他数据结构(例如锯齿状数组)更适合。
  • 为这些结构设计通用的,有用的方法并非易事。

IEnumerable的情况下,应该如何实现,即枚举元素的顺序是什么?多维数组中没有固有的顺序。

答案 3 :(得分:2)

零绑定单维数组同时实现IEnumerableIEnumerable<T>,但不幸的是,多维数组仅实现IEnumerable。 @Jader Dias的“解决方法”确实将多维数组转换为IEnumerable<T>,但代价很高:数组的每个元素都将被装箱。

这是一个不会导致每个元素装箱的版本:

public static class ArrayExtensions
{
    public static IEnumerable<T> ToEnumerable<T>(this T[,] target)
    {
        foreach (var item in target)
            yield return item;
    }
}

答案 4 :(得分:0)

Jagged数组也不支持IEnumerable<int>,因为多维结构实际上不是一个类型的数组,它们是一个类型数组的数组:

int[] singleDimensionArray = new int[10];
int[][] multiJagged = new int[10][];

Debug.WriteLine(singleDimensionArray is IEnumerable<int>);
Debug.WriteLine(multiJagged is IEnumerable<int[]>);
Debug.WriteLine(singleDimensionArray is IEnumerable);
Debug.WriteLine(multiJagged is IEnumerable);

打印真实,真实,真实,真实。

注意int[,]不是IEnumerable<int[]>,这是由于其他答案中指定的原因,即没有通用的方法来知道迭代哪个维度。使用锯齿状数组,没有太多的解释空间,因为语法很清楚它是一个数组数组。

答案 5 :(得分:0)

反思。 2d阵列已经存在。请列举一下。创建一个二维数组,其中包含一个或多个初始数组的分数和位置,包括重复值。

int[] secondmarks = {20, 15, 31, 34, 35, 50, 40, 90, 99, 100, 20};

IEnumerable<int> finallist = secondmarks.OrderByDescending(c => c);

int[,] orderedMarks = new int[2, finallist.Count()];

Enumerable.Range(0, finallist.Count()).ToList().ForEach(k => {orderedMarks[0, k] = (int) finallist.Skip(k).Take(1).Average();
orderedMarks[1, k] = k + 1;}); 

Enumerable.Range(0, finallist.Count()).Select(m => new {Score = orderedMarks[0, m], Place = orderedMarks[1, m]}).Dump();

结果:

Score Place

100     1
99      2 
90      3 
50      4 
40      5 
35      6    
34      7    
31      8    
20      9     
20     10 
15     11