C# 为什么不能在迭代器上下文中使用不安全的关键字?

C# 为什么不能在迭代器上下文中使用不安全的关键字?,c#,iterator,unsafe,C#,Iterator,Unsafe,在看这个问题时,乔恩回答得很好……''。还有一个类似的问题,在它关闭之前,我用指针hocus pocus回答 现在我开始尝试用指针来解决这个问题,好吧,它的边缘看起来很粗糙 public class ReadChar : IEnumerable<char> { private Stream _strm = null; private string _str = string.Empty; public ReadChar(string s) {

在看这个问题时,乔恩回答得很好……''。还有一个类似的问题,在它关闭之前,我用指针hocus pocus回答

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

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(); } } 公共类ReadChar:IEnumerable { 私有流_strm=null; 私有字符串_str=string.Empty; 公共ReadChar(字符串s) { 这个。_str=s; } 公共ReadChar(Stream strm) { 这个。_strm=strm; } 公共IEnumerator GetEnumerator() { if(this.\strm!=null和this.\u strm.CanRead和this.\u strm.CanSeek) { 返回ReverseReadStream(); } 如果(此长度大于0) { 返回ReverseRead(); } 返回null; } 私有IEnumerator ReverseReadStream() { long lIndex=此长度; while(lIndex!=0&&this.\u strm.Position!=0) { 本._strm.Seek(lIndex--,见Korigin.End); int nByte=this.\u strm.ReadByte(); 收益率(char)nByte; } } 私有IEnumerator ReverseRead() { 不安全的 { 修正(char*beg=this.\u str) { char*p=beg+this.\u str.Length; while(p-!=beg) { 收益率*p; } } } } IEnumerator IEnumerable.GetEnumerator() { 返回GetEnumerator(); } } 但发现C#编译器无法使用此实现处理此问题,但当C#编译器拒绝并出现错误CS1629-“不安全代码可能不会出现在迭代器中”时,它遭到了破坏

为什么会这样

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

26.1迭代器块。。。迭代器块包含不安全上下文是编译时错误(§27.1)。迭代器块总是 定义安全上下文,即使其声明嵌套在不安全上下文中


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

Eric Lippert在这里有一篇关于这个主题的优秀博文:

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

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

乱搞指针有什么显著的好处?

谢谢你的回答,但肯定使用固定关键字可以保证你在界限之内。。。???就像你几乎不会践踏不属于你的代码的东西…而且它是只读的,所以…@tommieb75:不正确,使用指针有无法验证的副作用。哦Eric Lippert讨论过这个。。。去读书吧!Eric关于迭代器块的整个系列是一个很好的资源!想想看,他的整个博客都很棒。想想
yield-return
在幕后是如何运作的。