Devi loop, e di dover ciclo, è più pulito di spostare l'anello in una funzione separata.
Ho creato un metodo di estensione per affrontare questo. Restituisce un elenco di tutte le eccezioni interne del tipo specificato, inseguendo Exception.InnerException e AggregateException.InnerExceptions.
Nel mio particolare problema, rincorrere le eccezioni interne era più complicato del solito, perché le eccezioni venivano lanciate dai costruttori delle classi che venivano invocate attraverso la riflessione. L'eccezione che stavamo catturando aveva una InnerException di tipo TargetInvocationException, e le eccezioni che dovevamo effettivamente vedere erano sepolte in profondità nell'albero.
public static class ExceptionExtensions
{
public static IEnumerable<T> innerExceptions<T>(this Exception ex)
where T : Exception
{
var rVal = new List<T>();
Action<Exception> lambda = null;
lambda = (x) =>
{
var xt = x as T;
if (xt != null)
rVal.Add(xt);
if (x.InnerException != null)
lambda(x.InnerException);
var ax = x as AggregateException;
if (ax != null)
{
foreach (var aix in ax.InnerExceptions)
lambda(aix);
}
};
lambda(ex);
return rVal;
}
}
L'utilizzo è piuttosto semplice. Se, per esempio, si desidera sapere se abbiamo incontrato un
catch (Exception ex)
{
var myExes = ex.innerExceptions<MyException>();
if (myExes.Any(x => x.Message.StartsWith("Encountered my specific error")))
{
// ...
}
}
fonte
2017-03-20 17:16:04
sto buttando un'eccezione in una delle mie classi, ma la mia classe è utilizzato da una libreria che inghiotte tutte le eccezioni e lancia la propria. Il problema è che l'eccezione della libreria è molto generica e ho bisogno di sapere quale specifica eccezione ho lanciato per sapere come gestire il problema. A peggiorare le cose, la libreria genererà la propria eccezione più volte annidata l'una nell'altra, a una profondità arbitraria. Ad esempio, pubblicherà 'LibraryException -> LibraryException -> LibraryException -> MyException'. La mia eccezione è sempre l'ultima della catena e non ha la sua eccezione interna. –
Oh, capisco perché potresti scendere al più profondo, avendolo fatto io stesso (e le varianti, come quelle più interne che derivano da un particolare tipo), ma non capisco quale sia il problema con ciò che hai già. –
Oh, capisco cosa intendi. Mi stavo chiedendo se ci fosse un altro modo di scriverlo. Mi sono abituato a usare 'LINQ' per fare quasi tutto ciò che mi sembra strano quando devo scrivere un ciclo. Lavoro principalmente con l'accesso ai dati, quindi lavoro praticamente con 'ICollections' per quasi tutto ciò che faccio. –