반복자 컨텍스트에서 안전하지 않은 키워드를 사용할 수 없는 이유는 무엇입니까?

StackOverflow https://stackoverflow.com/questions/2241417

  •  19-09-2019
  •  | 
  •  

문제

Jon이 훌륭한 답변을 한 이 질문을 보면...'반복자를 사용하여 텍스트 파일을 반대로 읽는 방법'.그리고 제가 포인터 hocus pocus를 사용하여 대답한 비슷한 질문이 있었습니다..'.net에는 텍스트 파일을 아래에서 위로 읽는 방법이 있습니다.'닫기 전에....

이제 포인터를 사용하여 이 문제를 해결하려고 했습니다. 좋습니다. 가장자리가 거칠고 거칠어 보입니다...

public class ReadChar : IEnumerable<char>
{
    private Stream _strm = null;
    private string _str = string.Empty;
    public ReadChar(string s)
    {
        this._str = s;
    }
    public ReadChar(Stream strm)
    {
        this._strm = strm;
    }
    public IEnumerator<char> GetEnumerator()
    {
        if (this._strm != null && this._strm.CanRead && this._strm.CanSeek)
        {
            return ReverseReadStream();
        }
        if (this._str.Length > 0)
        {
            return ReverseRead();
        }
        return null;
    }

    private IEnumerator<char> ReverseReadStream()
    {
        long lIndex = this._strm.Length;
        while (lIndex != 0 && this._strm.Position != 0)
        {
            this._strm.Seek(lIndex--, SeekOrigin.End);
            int nByte = this._strm.ReadByte();
            yield return (char)nByte; 
        }
    }

    private IEnumerator<char> ReverseRead()
    {
        unsafe
        {
            fixed (char* beg = this._str)
            {
                char* p = beg + this._str.Length;
                while (p-- != beg)
                {
                    yield return *p;
                }
            }
        }
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

그러나 C# 컴파일러가 이 구현을 사용하여 이를 처리할 수 없다는 사실을 발견했지만 C# 컴파일러가 오류 CS1629 - '안전하지 않은 코드가 반복자에 표시되지 않을 수 있습니다'와 함께 거부하자 큰 충격을 받았습니다.

왜 이렇게이다?

도움이 되었습니까?

해결책

Eric Lippert는 이 주제에 대한 훌륭한 블로그 게시물을 여기에 게시했습니다. 반복자 블록, 6부:왜 안전하지 않은 코드가 없나요?

다른 팁

내가 알고 싶은 것은 왜 포인터를 사용하는가입니다.간단히 말해서:

private IEnumerator<char> ReverseRead()
{
    int len = _str.Length;
    for(int i = 0; i < len; ++i)
        yield return _str[len - i - 1];
}

포인터를 조작하면 얻을 수 있는 강력한 이점은 무엇입니까?

이는 C# 사양의 일부일 뿐입니다.

26.1 반복자 블록 ...반복자 블록에 안전하지 않은 컨텍스트가 포함되는 것은 컴파일 타임 오류입니다(§27.1).반복자 블록은 선언이 안전하지 않은 컨텍스트에 중첩 될 때에도 항상 안전한 컨텍스트를 정의합니다.

아마도 컴파일러에 의해 생성된 코드는 '안전하지 않음'이라는 라벨이 붙지 않도록 검증 가능해야 합니다.포인터를 사용하려면 IEnumerator를 직접 구현해야 합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top