谁能告诉我,为什么下面的代码不工作,我所期望的方式?我试图写围绕一个StreamReader一个IEnumberable包装,但是当我使用的ElementAt就可以了,它读取连续字符从流无论我传递给ElementAt的索引。

在文件 “的test.txt” 包含 “ABCDEFGHIJKLMNOPQRSTUVWXYZ”。我期望的输出是:

  

aaaaaaaaaaaaaaaaaaaaaaaaaaa结果   bbbbbbbbbbbbbbbbbbbbbbbbbbb结果   ...

相反,我得到

  

ABCDEFGHIJKLMNOPQRSTUVWXYZ

和ArgumentOutOfRangeException被调用,即使我传递给ElementAt的迄今唯一索引为0。

MSDN表示:

  

如果源的类型实现IList <(中<(T>)>),即执行用于获得指定索引处的元素。否则,此方法获得指定的元素。

应该读取 “获得的元素”?如果是这样,这有点儿违背了懒惰名单的目的...

    static IEnumerable<char> StreamOfChars(StreamReader sr)
    {
        while (!sr.EndOfStream)
            yield return (char)sr.Read();
    }


    static void Main(string[] args)
    {
        using (StreamReader sr = new StreamReader("test.txt"))
        {
            IEnumerable<char> iec = StreamOfChars(sr);

            for (int i = 0; i < 26; ++i)
            {
                for (int j = 0; j < 27; ++j)
                {
                    char ch = iec.ElementAt(i);
                    Console.Write(ch);
                }
                Console.WriteLine();
            }
        }
    }
有帮助吗?

解决方案

是,MSDN文档应改为“获得下一个元素”。显然,你iec对象没有实现的IList 的实施的IEnumerable ,所以它是不可能做到随机读(没有当然它使用枚举到达随机索引扩展方法或东西)。向前只读是唯一可用的选择。

让我们来看看该ElementAt的方法的反汇编代码。显然,如果源集合不实现IList,我们在枚举检索当前项目:

public static TSource ElementAt<TSource>(this IEnumerable<TSource> source, int index)
{
    TSource current;
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    IList<TSource> list = source as IList<TSource>;
    if (list != null)
    {
        return list[index];
    }
    if (index < 0)
    {
        throw Error.ArgumentOutOfRange("index");
    }
    using (IEnumerator<TSource> enumerator = source.GetEnumerator())
    {
    Label_0036:
        if (!enumerator.MoveNext())
        {
            throw Error.ArgumentOutOfRange("index");
        }
        if (index == 0)
        {
            current = enumerator.Current;
        }
        else
        {
            index--;
            goto Label_0036;
        }
    }
    return current;
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top