问题
DebuggerHidden
is pretty handy for marking helper methods, making sure unhandled exceptions stop the debugger in a convenient place:

Unfortunately this doesn't seem to work with iterator blocks:

(if it did, the debugger would show the in
as the current statement in the second example).
While this is obviously a limitation of Visual Studio (for which I've submitted a report), is there some way I could perhaps work around this issue while still using an iterator block?
I am guessing that this happens because the compiler-generated code to implement the iterator isn't marked with [DebuggerHidden]
. Perhaps there's some way to convince the compiler to do that?
回答1:
Maybe not the answer you hoped for but as a workaround it could gain some points...not sure if you already dreamed this up.
Have a helper class that unwraps your iterator and then use an extension method to bring the wrapper into play on your iterator. I handle exceptions and rethrow. In VS2010 I had to strangely Uncheck the debug option 'Enable just my code' to get behavior close to what OP asked for. Leaving the option checked still drops you in the actual iterator but ik looks like one line too far.
That makes this answer more an experiment to prove and underpin that better compiler support is needed for the scenario to work.
Extension method 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();
}
}
Usage:
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);
}
}
来源:https://stackoverflow.com/questions/11056478/how-to-combine-debuggerhidden-with-iterator-block-methods