Perché non è possibile utilizzare una parola chiave non sicuro in un contesto iteratore?

StackOverflow https://stackoverflow.com/questions/2241417

  •  19-09-2019
  •  | 
  •  

Domanda

Nel guardare a questa domanda, che Jon ha fatto un buon lavoro nel rispondere ... ' Come leggere un file di testo con reversly iteratore '. E c'era una domanda simile in cui ho risposto usando puntatori Hocus Pocus .. '. net c'è un modo per leggere un file di testo dal basso in alto ' prima che fosse chiuso ....

Ora ho deciso di provare a risolvere questo utilizzando puntatori, ok, sembra hacker e ruvido intorno ai bordi ...

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();
    }
}

, ma ha scoperto che compilatore C # non è in grado di gestire questo utilizzando questa implementazione, ma è stato devastato quando il compilatore C # rifiutato con un errore di CS1629 - 'codice unsafe potrebbe non apparire in iteratori'

Perché è così?

È stato utile?

Soluzione

Eric Lippert ha un ottimo post sul blog su questo argomento qui: Iterator Blocchi, Parte sesta: perché nessun codice non sicuro

Altri suggerimenti

Quello che voglio sapere è perché si dovrebbe utilizzare i puntatori per questo a tutti. Perché non dire semplicemente:

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

Qual è il vantaggio convincente di fare in giro con puntatori?

E 'solo una parte del C # spec:

  

26.1 blocchi Iterator ... Si tratta di un errore di compilazione per un blocco iteratore per contenere un contesto non sicuro (§27.1). Un blocco iteratore sempre   definisce un contesto sicuro, anche quando la sua dichiarazione è annidato in un contesto pericoloso.

Presumibilmente, il codice che viene generato dal compilatore ha bisogno di essere verificabili in modo da non dover essere classificati 'non sicuro'. Se si desidera utilizzare i puntatori, si dovrà implementare IEnumerator se stessi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top