在看这个问题时,Jon在回答......'How to read a text file reversly with iterator'时做得很好。并且有一个类似的问题,我在使用指针hocus pocus ..'.net is there a way to read a text file from bottom to top'之后回答它......
现在我开始尝试使用指针尝试解决这个问题,好吧,它看起来很粗糙和边缘粗糙......
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而拒绝时遭到破坏 - “不安全的代码可能不会出现在迭代器中”
为什么会这样?
答案 0 :(得分:6)
Eric Lippert在这里有一篇关于这个主题的优秀博客文章:Iterator Blocks, Part Six: Why no unsafe code?
答案 1 :(得分:6)
我想知道的是为什么你会根本使用指针。为什么不简单地说:
private IEnumerator<char> ReverseRead()
{
int len = _str.Length;
for(int i = 0; i < len; ++i)
yield return _str[len - i - 1];
}
搞乱指针有什么吸引人的好处?
答案 2 :(得分:1)
这只是C#规范的一部分:
26.1迭代器块...迭代器块包含不安全的上下文(第27.1节)是编译时错误。一个迭代器块总是 定义一个安全的上下文,即使它的声明嵌套在一个不安全的上下文中。
据推测,编译器生成的代码需要是可验证的,以便不必标记为“不安全”。如果你想使用指针,你必须自己实现IEnumerator。