2010-01-18 5 views
7

Bazı sınıflar ile çalışıyorum, atma yaparken, nispeten derin bir InnerException ağacına sahip. Sorunun asıl sebebine sahip olan en içteki istisna üzerine giriş yapmak ve hareket etmek isterim.En içteki istisnayı bulmanın doğru yolu?

Şu anda

public static Exception getInnermostException(Exception e) { 
    while (e.InnerException != null) { 
     e = e.InnerException; 
    } 
    return e; 
} 

bu durum ağaçları işlemek için uygun yolu var mı benzer bir şey kullanıyorum

?

+0

Olası yinelenen http://stackoverflow.com/questions/3876456/find-the-inner-most-exception-without-using- a-while-döngüsü) – DavidRR

+0

Eğer bir şey varsa, diğeri çift, diğeri daha büyük ve kabul edilen doğru cevabı var. –

+0

Soru yaşı, her zaman bir yineleme belirtmek için yönetim kriteri değildir. Örneğin, diğer sorunun, bunun sahip olduğu görüşlerin sayısından on kat fazla olduğunu düşünün. Ayrıca, kabul edilen cevap sadece soruyu soran kişinin görüşünü yansıtmaktadır. Ve son olarak, [en çok oylanan cevap] 'ın (http://stackoverflow.com/a/5792456/1497596) diğer soruya da GetBaseException()' ı sunduğunu, ancak bazı durumlarda sınırlamalarını gösterdiğine dikkat edin. – DavidRR

cevap

10

Ben aşağıdaki kodu kullanarak en içteki özel durum alabilirsiniz düşünmek:

public static Exception getInnermostException(Exception e) { 
    return e.GetBaseException(); 
} 
+1

Teşekkürler, sormadan önce daha fazla API dokümanı okumam gerekiyor :) –

0

Tek kelimeyle, evet. Bunu daha iyi veya farklı bir şekilde düşünemiyorum. Bunun yerine bir uzantı yöntemi olarak eklemek istemediyseniz, ama aslında bir diğerinin yarısı bir düzine altı.

3

GetBaseException yöntemini kullanabilirsiniz. Çok kısa örnek:

try 
{ 
    try 
    { 
     throw new ArgumentException("Innermost exception"); 
    } 
    catch (Exception ex) 
    { 
     throw new Exception("Wrapper 1",ex); 
    } 
} 
catch (Exception ex) 
{ 
    // Writes out the ArgumentException details 
    Console.WriteLine(ex.GetBaseException().ToString()); 
} 
+0

+1, diğer cevabı daha çok beğendim, bu yüzden kabul ettim. –

+0

Yeterince adil, bununla tartışamazsınız :) Sadece bunu gösteren bir örnek kod/test demeti vereyim diye düşündüm. – AdaTheDev

0

birden çok temel nedeni (örneğin AggregateException ve ReflectionTypeLoadException) olabilir istisnalar vardır.

Ağaca gezinmek için class numaralı telefonumu oluşturdum ve ardından farklı ziyaretçileri her şeyi veya yalnızca kök nedenleri toplaması için yaptım. Örnek çıktılar here. Aşağıdaki ilgili kod pasajı.

public void Accept(ExceptionVisitor visitor) 
{ 
    Read(this.exception, visitor); 
} 

private static void Read(Exception ex, ExceptionVisitor visitor) 
{ 
    bool isRoot = ex.InnerException == null; 
    if (isRoot) 
    { 
     visitor.VisitRootCause(ex); 
    } 

    visitor.Visit(ex); 
    visitor.Depth++; 

    bool isAggregateException = TestComplexExceptionType<AggregateException>(ex, visitor, aggregateException => aggregateException.InnerExceptions); 
    TestComplexExceptionType<ReflectionTypeLoadException>(ex, visitor, reflectionTypeLoadException => reflectionTypeLoadException.LoaderExceptions); 

    // aggregate exceptions populate the first element from InnerExceptions, so no need to revisit 
    if (!isRoot && !isAggregateException) 
    { 
     visitor.VisitInnerException(ex.InnerException); 
     Read(ex.InnerException, visitor); 
    } 

    // set the depth back to current context 
    visitor.Depth--; 
} 

private static bool TestComplexExceptionType<T>(Exception ex, ExceptionVisitor visitor, Func<T, IEnumerable<Exception>> siblingEnumerator) where T : Exception 
{ 
    var complexException = ex as T; 
    if (complexException == null) 
    { 
     return false; 
    } 

    visitor.VisitComplexException(ex); 

    foreach (Exception sibling in siblingEnumerator.Invoke(complexException)) 
    { 
     visitor.VisitSiblingInnerException(sibling); 
     Read(sibling, visitor); 
    } 

    return true; 
} 
[while döngüsü kullanmadan en iç istisna bul?] Arasında (