Może nie jest to odpowiedź, na którą liczyłeś, ale jako obejście problemu może zdobyć kilka punktów ... nie jestem pewien, czy już to wymyśliłeś.
Masz klasę pomocniczą, która rozpakowuje twój iterator, a następnie użyj metody rozszerzenia, aby wprowadzić opakowanie do iteratora. Obsługuję wyjątki i ponownie rzucam. W VS2010 musiałem dziwnie odznaczyć opcję debugowania "Włącz tylko mój kod", aby uzyskać zachowanie zbliżone do tego, o co prosił OP. Pozostawienie zaznaczonej opcji powoduje, że jesteś w aktualnym iteratorze, ale ik wygląda na jedną linię za daleko.
To czyni tę odpowiedź bardziej eksperymentem, który ma udowodnić, że lepsze wsparcie dla kompilatora jest potrzebne, aby scenariusz zadziałał.
rozszerzenie klasy metoda pomocnika:
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();
}
}
Zastosowanie:
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);
}
}
Naprawdę nie rozumiem decyzji projektowych z ukrycia wyjątków w ten sposób. Widzę dwie sytuacje, które mogą wystąpić: 1) Piszecie bibliotekę do wykorzystania przez innych programistów. W tym przypadku nie mają one twoich źródeł, aw VS najniższym widocznym poziomem stosu będzie ThrowIterator. Więc to jest to, czego chciałeś w pierwszej kolejności. 2) Ten kod jest używany wyłącznie przez Twój zespół, wewnętrznie, do twojego projektu. W takim przypadku, dlaczego pozwoliłeś, aby niepokój wyjątkowy ześlizgnął się z tego i nie poradził sobie z tym? Na wypadek, gdyby był wyrzucany, nawet podczas debugowania, naprawdę chcesz zobaczyć, że jest w środku ThrowIterator, a najbardziej imp –
Z pewnością nie ma znaczenia, dlaczego używam tej funkcji. Jest tam i chcę tylko zobaczyć, jak sprawić, by działał we wszystkich okolicznościach. –
Ale jeśli jesteś ciekawy, rozważ metodę 'PerformQuery', która wyrzuca, jeśli argumenty nie mają sensu. Jest używany wyłącznie wewnętrznie przez nasz zespół.Wyjątek jest nieprzechwycony, ponieważ jest to kompilacja debugowania, która * w szczególności zapobiega * wychwytywaniu wyjątków * po prostu *, więc program Visual Studio zatrzymuje się dokładnie w odpowiednim miejscu. Jeśli projekt zamknął się zwykłym komunikatem "pojawił się problem", czy nie spowodowałoby to niepotrzebnego utrudnienia debugowania? My * wiemy * jest błąd, równie dobrze może zatrzymać się dokładnie na właściwej linii! –