为什么C#多层面阵列不执行综合<T>?
-
07-07-2019 - |
题
我只是注意到一个多层面阵列在C#没有实现 IEnumerable<T>
, 同时它不会实现 IEnumerable
.对于单一的维阵列,既 IEnumerable<T>
和 IEnumerable
实施。
为什么这种区别?如果一个多维的阵列 IEnumerable
, 当然,它还应执行有关的通用的版本吗?我注意到这一点,因为我试图用一个扩展方法上的多层面阵列,其失败的,除非你使用 Cast<T>
或类似;所以我绝对可以看到的的一个参数作出多层面阵列的实施 IEnumerable<T>
.
为澄清我的问题在代码,我希望以下代码打印 true
四倍,而实际上它的印花 true
, false
, true
, true
:
int[] singleDimensionArray = new int[10];
int[,] multiDimensional = new int[10, 10];
Debug.WriteLine(singleDimensionArray is IEnumerable<int>);
Debug.WriteLine(multiDimensional is IEnumerable<int>);
Debug.WriteLine(singleDimensionArray is IEnumerable);
Debug.WriteLine(multiDimensional is IEnumerable);
解决方案
CLR有两种不同的数组:向量,它们保证是一维的下限为0,更通用的数组可以有非零边界和一个等级比0。
从CLI规范的第8.9.1节开始:
此外,创建的矢量用 元素类型T,实现 接口 <代码> System.Collections.Generic.IList&LT; U&GT; 代码> (&#167; 8.7),其中U:= T。
我不得不说这对我来说似乎很奇怪。鉴于它已经实现了 IEnumerable
,我不明白它为什么不应该实现 IEnumerable&lt; T&gt;
。实现 IList&lt; T&gt;
并没有多大意义,但简单的通用接口会没问题。
如果你想要这个,你可以调用 Cast&lt; T&gt;
(如果你使用的是.NET 3.5)或编写自己的方法来迭代数组。为了避免强制转换,你必须编写自己的方法,找到每个维度的下限/上限,并以这种方式获取东西。不是非常愉快。
其他提示
有一种解决方法:您可以将任何多维数组转换为IEnumerable
public static class ArrayExtensions
{
public static IEnumerable<T> ToEnumerable<T>(this Array target)
{
foreach (var item in target)
yield return (T)item;
}
}
多层面阵列 不 阵列为目的的继承层次结构。他们是一个完全独立的类型。此外,这种类型没有很好的支持,该框架,两个可能的原因:
- 这不是真的那么有用。只有真正使用多层面阵列矩阵。对几乎其他任何东西,其他数据结构(例如锯齿状的阵列)更为适合。
- 这是不平凡的制定通用的、有用的方法,为这些结构。
在这种情况下的 IEnumerable
, 应该如何这已经实现,即在这以应的元素可以列举的?有没有秩序中固有的多层面阵列。
零绑定单维数组实现 IEnumerable
和 IEnumerable&lt; T&gt;
,但不幸的是,多维数组仅实现 IEnumerable
。 “变通方法”通过@Jader Dias确实将多维数组转换为 IEnumerable&lt; T&gt;
,但代价很高:数组的每个元素都将被装箱。
这是一个不会导致每个元素装箱的版本:
public static class ArrayExtensions
{
public static IEnumerable<T> ToEnumerable<T>(this T[,] target)
{
foreach (var item in target)
yield return item;
}
}
Jagged数组也不支持 IEnumerable&lt; int&gt;
,因为多维结构实际上不是一个类型的数组,它们是一个类型数组的数组:
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&lt; int []&gt;
,这是出于另一个指定的原因回答,即没有通用的方法来知道迭代哪个维度。使用锯齿状数组,没有太多的解释空间,因为语法很清楚它是一个数组数组。
反思。 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