반복자 컨텍스트에서 안전하지 않은 키워드를 사용할 수 없는 이유는 무엇입니까?
문제
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를 직접 구현해야 합니다.
제휴하지 않습니다 StackOverflow