0

作为输入,我有实现 IDataRecord(一些抽象表的行)的对象,所以它有索引器,并且通过给它一些整数,我可以检索某种类型的对象。作为输出,我的代码必须将该行中的某些单元格范围作为给定类型对象的数组。

所以我写了这个方法(是的,我知道,它可以很容易地转换为扩展方法,但我不需要这个,而且我真的不想让这个方法在我的课堂之外可见):

private static T[] GetRange<T>(IDataRecord row, int start, int length)
{
    var result = new List<T>();          

    for (int i = start; i < (start + length); i++)
    {
        result.Add((T)row[i]);
    }

    return result.ToArray();
}

它工作正常,但这种方法逻辑似乎很常见。那么,是否有任何方法可以在 .NET Framework FCL/BCL 中给出相同(或几乎相同)的结果?

4

4 回答 4

1

使用跳过采取

var rangeList = result.Skip(start - 1).Take(length);
于 2014-08-22T04:32:23.127 回答
1

不,它不在 BCL 中。

但是,您不应该先创建一个List<>然后将其复制到数组中。要么返回List<>自身(并使用适当的初始容量构造它),要么立即创建数组,如下所示:

private static T[] GetRange<T>(IDataRecord row, int start, int length)
{
    var result = new T[length];

    for (int i = 0; i < length; i++)
    {
        result[i] = (T)row[start + i];
    }

    return result;
}

这是一个替代方案(适用于所有 LINQ 爱好者):

// NB! Lazy enumeration
private static IEnumerable<T> GetRange<T>(IDataRecord row, int start, int length)
{
    return Enumerable.Range(start, length).Select(i => (T)row[i]);
}

我们在这里重复对问题的评论中所说的:接口System.Data.IDataRecord(在System.Data.dll汇编中)继承IEnumerable<>IEnumerable

于 2014-11-17T11:52:24.030 回答
0

如果你想“TakeARange”,你应该有一个集合作为输入参数。在这里你没有。

您只有一个具有索引器的 IDataRecord(例如单行)。您应该公开一个名为 Cells 的属性,该属性返回您在索引器实现中使用的列表。

您的方法应如下所示:

private static T[] TakeRange<T>(IEnumerable cells, int start, int length)
{
    return cells.Skip(start - 1).Take(length)
}
于 2014-08-22T07:46:16.387 回答
0

嗯..好像FCL/BCL中没有这样的方法

于 2014-08-26T05:06:42.613 回答