В рассмотрении этого вопроса, который Jon сделал прекрасное задание в ответе... 'Как считать текстовый файл reversly с итератором'. И был подобный вопрос, в котором я ответил на фокус-покус указателей использования.. '.net является там способом считать текстовый файл от нижней части до вершины', прежде чем это было закрыто....
Теперь я действительно намеревался пробовать, решают это использование указатели, хорошо, это смотрит hackish и грубо вокруг краев...
public class ReadChar : IEnumerable{ 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 GetEnumerator() { if (this._strm != null && this._strm.CanRead && this._strm.CanSeek) { return ReverseReadStream(); } if (this._str.Length > 0) { return ReverseRead(); } return null; } private IEnumerator 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 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 - 'Небезопасный код не может появиться в итераторах'
Почему то, что так?
У Эрика Липперта есть отличная статья в блоге на эту тему здесь: Блоки итераторов, часть шестая: Почему нет небезопасного кода?
Это просто часть спецификации C #:
26.1 Блоки итератора ... Это ошибка времени компиляции, когда блок итератора содержит небезопасный контекст (§27.1). Блок итератора всегда определяет безопасный контекст, даже если его объявление вложено в небезопасный контекст.
Предположительно, код, сгенерированный компилятором, должен быть проверяемым, чтобы его не называли «небезопасным». Если вы хотите использовать указатели, вам придется реализовать IEnumerator самостоятельно.
Я хочу знать, почему вы вообще можете использовать для этого указатели. Почему бы просто не сказать:
private IEnumerator<char> ReverseRead()
{
int len = _str.Length;
for(int i = 0; i < len; ++i)
yield return _str[len - i - 1];
}
В чем убедительное преимущество возиться с указателями?