Comment combiner DebuggerHidden avec des méthodes de bloc iterator?

DebuggerHidden est très pratique pour marquer les méthodes d’assistance, en s’assurant que les exceptions non gérées arrêtent le débogueur à un endroit pratique:

entrez la description de l'image ici

Malheureusement, cela ne semble pas fonctionner avec les blocs d’iterators:

entrez la description de l'image ici

(Si c’est le cas, le débogueur affichera l’entrée comme l’instruction courante dans le deuxième exemple).

Bien que ce soit évidemment une limitation de Visual Studio (pour lequel j’ai soumis un rapport ), y a-t-il un moyen de contourner ce problème tout en utilisant un bloc iterator?

Je suppose que cela se produit car le code généré par le compilateur pour implémenter l’iterator n’est pas marqué avec [DebuggerHidden] . Peut-être y a-t-il un moyen de convaincre le compilateur de le faire?

Peut-être pas la réponse que vous espériez, mais comme solution de contournement, il pourrait gagner quelques points… je ne suis pas sûr que vous en ayez déjà rêvé.

Ayez une classe d’assistance qui ouvre votre iterator, puis utilisez une méthode d’extension pour faire en sorte que l’encapsuleur soit en jeu sur votre iterator. Je gère les exceptions et renoue. Dans VS2010, je devais étrangement décocher l’option de débogage «Activer uniquement mon code» pour obtenir un comportement proche de ce que l’OP demandait. Laisser l’option cochée vous laisse toujours tomber dans l’iterator réel mais ik ressemble trop à une ligne.

Cela fait de cette réponse davantage une expérience visant à prouver et à soutenir qu’un meilleur support du compilateur est nécessaire pour que le scénario fonctionne.

Classe d’assistance de méthode d’extension:

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

Wrapper:

 public class HiddenEnumerator : IEnumerable, IEnumerator { IEnumerator _actual; private HiddenEnumerator(IEnumerable enu) { _actual = enu.GetEnumerator(); } public static HiddenEnumerator Enumerable(IEnumerable enu ) { return new HiddenEnumerator(enu); } public T Current { [DebuggerHidden] get { T someThing = default(T); try { someThing = _actual.Current; } catch { throw new Exception(); } return someThing; } } public IEnumerator 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(); } } 

Usage:

  public IEnumerable 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); } }