Почему Вы не можете использовать небезопасное ключевое слово в контексте итератора?

В рассмотрении этого вопроса, который 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 - 'Небезопасный код не может появиться в итераторах'

Почему то, что так?

6
задан Community 23 May 2017 в 12:24
поделиться

3 ответа

У Эрика Липперта есть отличная статья в блоге на эту тему здесь: Блоки итераторов, часть шестая: Почему нет небезопасного кода?

6
ответ дан 8 December 2019 в 18:35
поделиться

Это просто часть спецификации C #:

26.1 Блоки итератора ... Это ошибка времени компиляции, когда блок итератора содержит небезопасный контекст (§27.1). Блок итератора всегда определяет безопасный контекст, даже если его объявление вложено в небезопасный контекст.

Предположительно, код, сгенерированный компилятором, должен быть проверяемым, чтобы его не называли «небезопасным». Если вы хотите использовать указатели, вам придется реализовать IEnumerator самостоятельно.

1
ответ дан 8 December 2019 в 18:35
поделиться

Я хочу знать, почему вы вообще можете использовать для этого указатели. Почему бы просто не сказать:

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

В чем убедительное преимущество возиться с указателями?

6
ответ дан 8 December 2019 в 18:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: