我对泛型非常陌生,我正在尝试为自己构建一个辅助方法来创建二维对象数组,如下所示。
public static class CarouselHelper<T> where T : new()
{
public static IEnumerable<T[,]> BuildCarousel(T data, int rows, int columns)
{
T [,] carousel = new T[rows, columns];
List<T[,]> slides = new List<T[,]>();
int rowCount = 0, columnCount = 0, itemCount = 1;
foreach (var item in data)
{
if (itemCount % 2 == 0)
{
rowCount = 0;
columnCount = columnCount++;
}
carousel[rowCount, columnCount] = item;
if (rowCount == rows && columnCount == columns)
{
slides.Add(carousel);
carousel = new T[rows, columns];
}
itemCount = itemCount++;
}
return null;
}
}
我按如下方式调用方法
var bob = Common.CarouselHelper<List<VideoListModel>>.BuildCarousel(ds, 2, 4);
我跑步时遇到以下错误,不知道从哪里开始?
foreach语句不能对“T”类型的变量进行操作,因为“T”不包含“GetEnumerator”的公共定义
答案 0 :(得分:0)
您的错误消息仍然存在。您试图迭代T
实例,但不确定是否可能。
如果不知道什么是ds
类型,很难说明如何解决这个问题,但您应该将方法声明更改为:
public static IEnumerable<T[,]> BuildCarousel(IEnumerable<T> data, int rows, int columns)
顺便说一句。您永远不会增加rowCount
,因此它始终设置为0
。你确定算法是正确的吗?
答案 1 :(得分:0)
基本上你不能使用你的泛型类型上可能不存在的任何方法,它们仍然是静态类型的,
即你有
foreach (var item in data)
并且数据是类型T,因此T必须是IEnumerable,因此您需要明确约束泛型类型,即
public static class CarouselHelper<T> where T : new(), IEnumerable
答案 2 :(得分:0)
根本问题是T
是您的基本数据类型。它不是可枚举的:IEnumerable<T>
需要在方法原型的data
参数声明中。
但它看起来非常复杂。你为什么不做更简单的事情呢?
public static class CarouselHelper<T>
{
public static IEnumerable<T[,]> BuildCarousel( IEnumerable<T> data, int rows, int cols )
{
List<T[,]> slides = new List<T[,]>();
using ( IEnumerator<T> enumerator = data.GetEnumerator() )
{
bool moved = true ;
do
{
T [,] carousel = new T[ rows, cols ] ;
for ( int i = 0 ; i < rows ; ++i )
{
for ( int j = 0 ; j < cols ; ++j )
{
moved = enumerator.MoveNext() ;
T currentCell = moved ? enumerator.Current : default(T) ;
carousel[i,j] = currentCell ;
}
}
slides.Add(carousel) ;
} while ( moved ) ;
}
return slides ;
}
}
上面以行主要顺序构建了2d数组;如果你希望它们以列主要顺序构建,只需在核心交换嵌套的for
循环:
T [,] carousel = new T[ rows, cols ] ;
for ( int j = 0 ; j < cols ; ++j )
{
for ( int i = 0 ; i < rows ; ++i )
{
moved = enumerator.MoveNext() ;
T currentCell = moved ? enumerator.Current : default(T) ;
carousel[i,j] = currentCell ;
}
}
slides.Add(carousel) ;
更好,因为你正在返回IEnumerable<T>
...让评价变得懒惰:
public static class CarouselHelper<T>
{
public static IEnumerable<T[,]> BuildCarousel( IEnumerable<T> data, int rows, int cols )
{
using ( IEnumerator<T> enumerator = data.GetEnumerator() )
{
bool moved = true ;
do
{
T [,] carousel = new T[ rows, cols ] ;
for ( int i = 0 ; i < rows ; ++i )
{
for ( int j = 0 ; j < cols ; ++j )
{
moved = enumerator.MoveNext() ;
T currentCell = moved ? enumerator.Current : default(T) ;
carousel[i,j] = currentCell ;
}
}
yield return carousel ;
} while ( moved ) ;
}
}
}