문제

누구든지 다음 코드가 내가 기대하는 방식으로 작동하지 않는 이유를 말해 줄 수 있습니까? 스트림 리더 주위에 ienbilberable 래퍼를 쓰려고 노력하고 있지만 ElementAT를 사용하면 ElementAT로 전달되는 인덱스에 관계없이 스트림에서 순차적 문자를 읽습니다.

"test.txt"파일에는 "abcdefghijklmnopqrstuvwxyz"가 포함되어 있습니다. 나는 출력이 다음을 기대할 것이다.

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
BBBBBBBBBBBBBBBBBBBBBBBBB
...

대신 나는 얻는다

abcdefghijklmnopqrstuvwxyz

내가 지금까지 Elementat에 전달한 유일한 색인은 0이지만 ArgumentOutOfRangeException이 호출됩니다.

MSDN 말 :

소스 유형이 ilist <(of <(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 객체는 구현되지 않습니다 일리스트 그리고 구현 ienumerable, 따라서 임의의 읽기를 수행하는 것은 불가능합니다 (물론 확장 방법이나 열거자를 사용하여 임의의 인덱스에 도달하는 것없이). Forward 전용 읽기는 유일하게 사용 가능한 옵션입니다.

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