2010-02-11 9 views
5

Patrząc na to pytanie, Jon wykonał dobrą robotę, odpowiadając ... "How to read a text file reversly with iterator". I nie było podobne pytanie, w którym odpowiedział stosując wskaźniki Hokus pokus .. „.net is there a way to read a text file from bottom to top” zanim został zamknięty ....Dlaczego nie można użyć niebezpiecznego słowa kluczowego w kontekście iteratora?

Teraz nie określono, aby spróbować rozwiązać ten problem za pomocą wskaźników, ok, to wygląda hackish i szorstki na brzegach ...

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

ale odkrył, że kompilator C# nie można obsługiwać za pomocą tego wdrożenia, ale został zniszczony podczas kompilator C# odmówił z CS1629 błędu - „niebezpieczny kod nie może pojawić się w iteratory”

Dlaczego to jest takie?

+0

Pomyśl o tym, jak "zwrot z inwestycji" działa pod maską. –

Odpowiedz

1

To tylko część C# specyfikacji:

26.1 Iterator bloki ... To jest błąd czasu kompilacji na blok iterator zawiera niebezpiecznego kontekstu (§27.1). Blok iteracyjny zawsze definiuje bezpieczny kontekst, nawet jeśli jego deklaracja jest zagnieżdżona w niebezpiecznym kontekście.

Prawdopodobnie kod generowany przez kompilator musi być możliwy do zweryfikowania, aby nie być oznaczony jako "niebezpieczny". Jeśli chcesz używać wskaźników, musisz sam wdrożyć IEnumerator.

+0

Dziękuję za odpowiedź, ale z pewnością użycie stałego słowa kluczowego gwarantuje, że znajdujesz się w granicach ... ??? tak jakbyś nie chciał deptać czegoś, co nie należy do twojego kodu ... i jest to tylko do odczytu, więc ... – t0mm13b

+0

@ tommieb75: Nie prawda, są niezweryfikowalne efekty uboczne za pomocą wskaźników. Eric Lippert omawia to ... i czyta! – codekaizen

+0

Dzięki! ;) Ja też to czytam i zastanawiam się nad tym ... – t0mm13b

6

Co chcę wiedzieć, dlaczego chcesz użyć wskaźników dla tego w ogóle. Dlaczego po prostu nie powiesz:

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

Jaka jest niewątpliwa korzyść z używania wskaźników?