2012-06-15 22 views
5

DebuggerHidden là khá tiện dụng để đánh dấu phương pháp helper, đảm bảo hợp ngoại lệ unhandled ngăn chặn các chương trình gỡ rối ở một nơi thuận tiện:Làm thế nào để kết hợp DebuggerHidden với các phương thức khối lặp?

                  enter image description here

Thật không may này dường như không làm việc với khối lặp:

          enter image description here

(nếu có, trình gỡ lỗi sẽ hiển thị in làm tuyên bố hiện tại trong ví dụ thứ hai).

Trong khi điều này rõ ràng là một giới hạn của Visual Studio (mà tôi đã submitted a report), có cách nào tôi có lẽ có thể làm việc xung quanh vấn đề này trong khi vẫn sử dụng một khối lặp?

Tôi đoán rằng điều này xảy ra vì mã do trình biên dịch tạo để triển khai trình lặp không được đánh dấu bằng [DebuggerHidden]. Có lẽ có một số cách để thuyết phục trình biên dịch làm điều đó?

+0

Tôi thực sự không hiểu quyết định thiết kế lại ngoại lệ trốn theo cách này. Tôi có thể thấy hai tình huống có thể xảy ra: 1) Bạn đang viết thư viện để các nhà phát triển khác sử dụng. Trong trường hợp này, chúng không có nguồn của bạn và trong VS mức stack thấp nhất có thể nhìn thấy sẽ là ThrowIterator. Vì vậy, đó là những gì bạn muốn ở nơi đầu tiên. 2) Mã này chỉ được nhóm của bạn sử dụng, nội bộ, cho dự án của bạn. Trong trường hợp này, tại sao bạn lại để cho một phiếu ngoại lệ không bị bắt như vậy và không xử lý nó? Trong trường hợp nó bị ném, ngay cả khi gỡ lỗi, bạn thực sự muốn thấy rằng nó nằm trong ThrowIterator, và hầu hết imp –

+0

Chắc chắn nó không quan trọng tại sao tôi đang sử dụng tính năng này. Nó ở đó và tôi chỉ muốn xem cách làm cho nó hoạt động trong mọi hoàn cảnh. –

+0

Nhưng nếu bạn tò mò, hãy xem xét phương thức 'PerformQuery', nó sẽ ném nếu đối số không có ý nghĩa. Nó chỉ được sử dụng trong nội bộ bởi nhóm của chúng tôi.Ngoại lệ là không bị bắt vì nó là một xây dựng gỡ lỗi, mà * đặc biệt tránh * bắt ngoại lệ * chỉ * để Visual Studio dừng lại ở đúng nơi. Nếu dự án chỉ đóng cửa với một thông báo chung "có một vấn đề", thì điều đó không chỉ làm cho việc gỡ lỗi không cần thiết khó khăn hơn? Chúng tôi * biết * có một lỗi, cũng có thể dừng lại ở đúng đường thẳng! –

Trả lời

0

Có lẽ không phải là câu trả lời bạn mong đợi nhưng như một giải pháp, nó có thể đạt được một số điểm ... không chắc chắn nếu bạn đã mơ ước này lên.

Có lớp trợ giúp mở trình lặp của bạn và sau đó sử dụng một phương pháp mở rộng để đưa trình bao bọc vào trình lặp của bạn. Tôi xử lý ngoại lệ và quay lại. Trong VS2010 tôi đã phải bỏ chọn tùy chọn gỡ lỗi một cách kỳ lạ 'Chỉ kích hoạt mã của tôi' để có được hành vi gần với những gì mà OP yêu cầu. Rời khỏi tùy chọn kiểm tra vẫn giảm bạn trong vòng lặp thực tế nhưng ik trông giống như một dòng quá xa.

Điều đó làm cho câu trả lời này thêm một thử nghiệm để chứng minh và củng cố rằng hỗ trợ trình biên dịch tốt hơn là cần thiết cho kịch bản hoạt động.

mở rộng phương pháp helper class:

public static class HiddenHelper 
{ 
    public static HiddenEnumerator<T> Hide<T>(this IEnumerable<T> enu) 
    { 
     return HiddenEnumerator<T>.Enumerable(enu); 
    } 
} 

Wrapper:

public class HiddenEnumerator<T> : IEnumerable<T>, IEnumerator<T> 
    { 
     IEnumerator<T> _actual; 
     private HiddenEnumerator(IEnumerable<T> enu) 
     { 
      _actual = enu.GetEnumerator(); 
     } 

     public static HiddenEnumerator<T> Enumerable(IEnumerable<T> enu) 
     { 
      return new HiddenEnumerator<T>(enu); 
     } 

     public T Current 
     { 
      [DebuggerHidden] 
      get 
      { 
       T someThing = default(T); 
       try 
       { 
        someThing = _actual.Current; 
       } 
       catch 
       { 
        throw new Exception(); 
       } 
       return someThing; 
      } 
     } 

     public IEnumerator<T> GetEnumerator() 
     { 
      return this; 
     } 

     IEnumerator IEnumerable.GetEnumerator() 
     { 
      throw new NotImplementedException(); 
     } 

     public void Dispose() 
     { 
      _actual.Dispose(); 
     } 

     object IEnumerator.Current 
     { 
      get { return _actual.Current; } 
     } 

     [DebuggerHidden] 
     public bool MoveNext() 
     { 
       bool move = false; 
       try 
       { 
        move = _actual.MoveNext(); 
       } 
       catch 
       { 
        throw new IndexOutOfRangeException(); 
       } 
       return move; 
     } 

     public void Reset() 
     { 
      _actual.Reset(); 
     } 
    } 

Cách sử dụng:

 public IEnumerable<int> Power(int number, int exponent) 
     { 
      int counter = 0; 
      int result = 1; 
      while (counter++ < exponent) 
      { 
       if (result>Int16.MaxValue) throw new Exception(); 
       result = result * number; 
       yield return result; 
      } 
     } 

     public void UseIt() 
     { 
      foreach(var i in Power(Int32.MaxValue-1,5).Hide()) 
      { 
       Debug.WriteLine(i); 
      } 
     } 
+0

Có vẻ như không hoạt động theo cách tôi mô tả trong câu hỏi: (Ngoài ra, ví dụ "sử dụng" của bạn không thực sự ném chút nào, có hoặc không có 'Ẩn'. –

+0

Vâng, nó có khả năng chọn một khung xếp chồng từ một đoạn mã đã được thực hiện ... thử/lỗi đã bắt đầu ... – rene

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