2010-02-11 29 views
5

Khi xem câu hỏi này, Jon đã làm tốt việc trả lời ... 'How to read a text file reversly with iterator'. Và có một câu hỏi tương tự, trong đó tôi đã trả lời bằng cách sử dụng con trỏ lấy nét tập trung .. '.net is there a way to read a text file from bottom to top' trước khi nó bị đóng ...Tại sao bạn không thể sử dụng từ khóa không an toàn trong ngữ cảnh trình lặp?

Bây giờ tôi đã cố gắng giải quyết vấn đề này bằng cách sử dụng con trỏ, ok xung quanh các cạnh ...

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

nhưng phát hiện ra rằng biên dịch C# không thể xử lý này sử dụng thực hiện điều này, nhưng đã bị tàn phá khi biên dịch C# từ chối với một CS1629 lỗi - 'mã không an toàn có thể không xuất hiện trong vòng lặp'

Tại sao vậy?

+0

Hãy suy nghĩ về cách 'lợi nhuận hoạt động' hoạt động dưới sự giám sát. –

Trả lời

1

Nó chỉ là một phần của C# spec:

26,1 khối Iterator ... Đó là một lỗi thời gian biên dịch cho một khối iterator để chứa một bối cảnh không an toàn (§27.1). Một khối lặp luôn luôn định nghĩa một bối cảnh an toàn, ngay cả khi khai báo của nó được lồng trong một bối cảnh không an toàn.

Có lẽ, mã do trình biên dịch tạo ra cần phải được kiểm chứng để không bị dán nhãn 'không an toàn'. Nếu bạn muốn sử dụng con trỏ, bạn sẽ phải tự mình thực hiện IEnumerator.

+0

Cảm ơn câu trả lời của bạn, nhưng chắc chắn việc sử dụng từ khóa cố định được đảm bảo rằng bạn đang ở trong ranh giới ... ??? như bạn khó có thể chà đạp cái gì đó không thuộc về mã của bạn ... và nó chỉ đọc, vì vậy ... – t0mm13b

+0

@ tommieb75: Không đúng, có những tác dụng phụ không thể xác minh được bằng cách sử dụng con trỏ. Ồ, Eric Lippert thảo luận về điều này ... để đọc! – codekaizen

+0

Cảm ơn! ;) Đang đọc nó quá và đang cân nhắc về nó ... – t0mm13b

6

Những gì tôi muốn biết là tại sao bạn sẽ sử dụng con trỏ cho điều này chút nào. Tại sao không chỉ đơn giản là nói:

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

Lợi ích hấp dẫn của việc rối tung với con trỏ là gì?

Các vấn đề liên quan