8

在查看 Jon 在回答方面做得很好的这个问题时......“如何使用迭代器反向读取文本文件”。还有一个类似的问题,我用指针 hocus pocus 回答了。.net有没有办法在关闭之前从下到上读取文本文件......

现在我确实开始尝试使用指针来解决这个问题,好吧,它看起来很粗糙而且边缘粗糙......

公共类 ReadChar : IEnumerable<char>
{
    私有流 _strm = null;
    私有字符串 _str = string.Empty;
    公共读取字符(字符串 s)
    {
        this._str = s;
    }
    公共读取字符(流 strm)
    {
        this._strm = strm;
    }
    公共 IEnumerator<char> GetEnumerator()
    {
        if (this._strm != null && this._strm.CanRead && this._strm.CanSeek)
        {
            返回反向读取流();
        }
        如果(this._str.Length > 0)
        {
            返回反向读取();
        }
        返回空值;
    }

    私有 IEnumerator<char> ReverseReadStream()
    {
        长 lIndex = this._strm.Length;
        而 (lIndex != 0 && this._strm.Position != 0)
        {
            this._strm.Seek(lIndex--, SeekOrigin.End);
            int nByte = this._strm.ReadByte();
            收益返回 (char)nByte;
        }
    }

    私有 IEnumerator<char> ReverseRead()
    {
        不安全
        {
            固定 (char* beg = this._str)
            {
                char* p = beg + this._str.Length;
                而 (p-- != 乞求)
                {
                    收益回报 *p;
                }
            }
        }
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        返回 GetEnumerator();
    }
}

但发现 C# 编译器无法使用此实现处理此问题,但当 C# 编译器以错误 CS1629 拒绝时被摧毁 - '不安全代码可能不会出现在迭代器中'

为什么呢?

4

3 回答 3

9

Eric Lippert 在这里有一篇关于这个主题的优秀博客文章:迭代器块,第六部分:为什么没有不安全的代码?

于 2010-02-11T00:34:57.673 回答
6

我想知道的是为什么你会为此使用指针。为什么不简单地说:

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

搞乱指针有什么令人信服的好处?

于 2010-02-12T20:03:40.603 回答
1

它只是 C# 规范的一部分:

26.1 迭代器块...迭代器块包含不安全上下文(第 27.1 节)是编译时错误。一个迭代器块总是定义一个安全的上下文,即使它的声明嵌套在一个不安全的上下文中。

据推测,编译器生成的代码需要可验证,以免被标记为“不安全”。如果要使用指针,则必须自己实现 IEnumerator。

于 2010-02-11T00:31:56.027 回答