C#Generics无法通过列表

时间:2014-01-29 01:09:28

标签: c# generics anonymous-types

我对泛型非常陌生,我正在尝试为自己构建一个辅助方法来创建二维对象数组,如下所示。

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”的公共定义

3 个答案:

答案 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

请参阅http://msdn.microsoft.com/en-us/library/d5x73970.aspx

答案 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 ) ;
    }
  }
}