5

DebuggerHidden는 확인되지 않은 예외가 편리한 장소에 디버거를 중지 헬퍼 메소드를 표시 만들기위한 매우 편리합니다 반복자 블록 :DebuggerHidden과 반복자 블록 메소드를 결합하는 방법은 무엇입니까?</p> <p>                  <img src="https://i.stack.imgur.com/6JH5q.png" alt="enter image description here"></p> <p>불행하게도이 작동하지 않는 것 :

          enter image description here

(있는 경우 디버거는 두 번째 예에서는 in을 현재 문으로 표시합니다.

Visual Studio의 제한 사항 (분명히 내가 submitted a report 임)이 반복기 블록을 사용하면서이 문제를 해결할 수있는 방법이 있습니까?

필자는 반복기를 구현하는 컴파일러 생성 코드가 [DebuggerHidden]으로 표시되지 않았기 때문에 이러한 현상이 발생한다고 생각합니다. 아마도 컴파일러에게 그렇게하도록 설득 할 수있는 방법이 있을까요?

+0

정말 숨어 예외의 설계 결정이 방법을 이해하지 않습니다. 두 가지 상황이 발생할 수 있습니다. 1) 다른 개발자가 사용할 라이브러리를 작성 중입니다. 이 경우 소스에 소스가없고 VS에서 보이는 가장 낮은 스택 레벨은 ThrowIterator가됩니다. 그래서 그것은 당신이 처음에 원했던 것입니다. 2)이 코드는 팀 내부에서 프로젝트에만 사용됩니다. 이 경우 왜 잡히지 않은 예외를 처리하고 처리하지 않겠습니까? 디버깅 할 때에도 ThrowIterator 내부에 있음을 실제로보고 싶습니다. 대부분의 imp –

+0

분명히이 기능을 사용하는 이유는 중요하지 않습니다. 거기에 있으며 모든 상황에서 작동하도록하는 방법을보고 싶습니다. –

+0

그러나 궁금한 점이 있다면 인수가 의미가 없으면 throw하는'PerformQuery' 메서드를 고려하십시오. 그것은 우리 팀에 의해서만 내부적으로 사용됩니다.예외는 디버그 빌드이기 때문에 캐치되지 않습니다. * Visual Studio가 정확히 올바른 위치에 멈추도록 예외 * 잡기를 특별히 방지합니다. 프로젝트가 일반적인 "문제가 있습니다"메시지로 막 닫힌 경우 디버깅을 불필요하게 어렵게 만듭니 까? 우리는 버그가 있다는 것을 알고 있습니다. 정확히 올바른 라인에서 중지 할 수도 있습니다! –

답변

0

아마도 당신이 바라는 대답이 아니지만 해결 방법으로 몇 가지 포인트를 얻을 수 있습니다 ... 이미 꿈꿔 왔는지 확실하지 않습니다.

반복기의 랩퍼를 해제 한 다음 확장 메서드를 사용하여 반복기에서 래퍼를 재생하도록하십시오. 예외를 처리하고 다시 전합니다. VS2010에서 이상하게도 디버그 옵션 인 'Enable my code'를 선택 취소하면 OP가 요구 한 것과 비슷한 동작을 얻을 수있었습니다. 체크 된 옵션을 그대로두면 실제 반복자에서 빠져 나옵니다. 그러나 ik는 너무 멀리 한 라인처럼 보입니다.

이 답변은 시나리오가 작동하기 위해 더 나은 컴파일러 지원이 필요하다는 것을 증명하고 입증하는 실험입니다.

확장 방법 헬퍼 클래스 :

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

래퍼 :

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

사용법 :

 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

질문에 설명 된 방식대로 작동하지 않는 것 같습니다. (또한 "사용"예제는 실제로는 전혀 숨기지 않습니다. 숨기기 여부와 관계 없습니다. –

+0

예, 스택 프레임을 선택할 수 있습니다. 이미 실행 된 코드 ... 시행 착오가 시작되었습니다. – rene

관련 문제