2012-04-12 15 views
11

Kodumda, System.Reflection.TargetInvocationException'un atıldığı bir durumla karşılaşıyorum. Belirli bir durumda, root istisnasını nasıl ele almak istediğimi biliyorum, ancak diğer istisnaları da atmak istiyorum. Bunu yapmanın iki yolunu düşünebilirim, ama hangisinin daha iyi olduğundan emin değilim. İç istisnanın türünü kontrol etme

2.

try 
{ 
    //code 
} 
catch (System.Reflection.TargetInvocationException ex) 
{ 
    try 
    { 
     throw ex.InnerException; 
    } 
    catch (SpecificException exSpecific) 
    { 
     //fix 
    } 
} 

Ben genelde özel durumlar atma yavaş farkındayım, bu yüzden ilk yöntem muhtemelen daha hızlı olacak hissediyorum

try 
{ 
    //code 
} 
catch (System.Reflection.TargetInvocationException ex) 
{ 
    if (typeof(ex.InnerException) == typeof(SpecificException)) 
    { 
     //fix 
    } 
    else 
    { 
     throw ex.Innerexception; 
    } 
} 

1.

. Alternatif olarak, bunu düşünmediğim daha iyi bir yolu var mı?

+2

2, büyüleyici. – Gabber

+0

Soru: 'TargetInvocationException' adındaki çağrı nedir? Kodun mu yoksa üçüncü taraf mı? –

+0

db'den okunan kod oluşturuldu. – geekchic

cevap

17

Önerilen çözümlerinizin her birinin kendi sorunu vardır.

İlk yöntem, iç istisnanın türünün, beklediğiniz türde tam olarak olduğunu kontrol eder. Bu, türetilmiş bir türün eşleşmeyeceği anlamına gelir;

İkinci yöntem, Dan Puzey'in bahsettiği gibi, iç istifin yığın izinin geçerli yığın konumu ile üzerine yazmaktadır. Yığın izini yok etmek, bir hatayı düzeltmek için gereksinim duyduğunuz bir ipucunu yok edebilir. Eğer yapabilirsiniz çıkıyor bir özel durum atması istiyorsanız

try 
{ 
    // Do something 
} 
catch (TargetInvocationException ex) 
{ 
    if (ex.InnerException is SpecificException) 
    { 
     // Handle SpecificException 
    } 
    else if (ex.InnerException is SomeOtherSpecificException) 
    { 
     // Handle SomeOtherSpecificException 
    } 
    else 
    { 
     throw; // Always rethrow exceptions you don't know how to handle. 
    } 
} 

:

çözüm DarkGray Nick'in öneriyle ve (else olarak) kendime ait bir katma önerisi ile, yayınlanan temelde ne İşle, throw ex; yapmayın, çünkü bu yığın izinin üzerine yazılır. Bunun yerine yığın izlemeyi koruyan throw; kullanın. Temelde "Bu catch maddesine girmek istemedim, istisna asla yakalanmadığımı iddia et" anlamına gelir.

Güncelleme: C# 6.0 İstisna Filtreler aracılığıyla çok daha iyi bir sözdizimi sunmaktadır: 1 daha okunabilir ve bakış başarım açısından muhtemelen daha iyidir imho

try 
{ 
    // Do something 
} 
catch (TargetInvocationException ex) when (ex.InnerException is SpecificException) 
{ 
    // Handle SpecificException 
} 
catch (TargetInvocationException ex) when (ex.InnerException is SomeOtherSpecificException) 
{ 
    // Handle SomeOtherSpecificException 
} 
+0

+1; throw; 've' throw ex; – geekchic

-2
try 
{ 
    //code 
} 
catch (System.Reflection.TargetInvocationException ex) 
{ 
    if (ex.InnerException is SpecificException) 
    { 
     //fix 
    } 
    else 
    { 
     throw ex.InnerException; 
    } 
} 

veya

try 
{ 
    //code 
} 
catch (System.Reflection.TargetInvocationException ex) 
{ 
    SpecificException spExc = ex.InnerException as SpecificException; 
    if (spExc != null) 
    { 
     bla-bla spExc 
    } 
    else 
    { 
     throw ex.InnerException; 
    } 
} 

veya

try 
{ 
    //code 
} 
catch (System.Reflection.TargetInvocationException ex) 
{ 
    if (ex.InnerException.GetType() == typeof(SpecificException)) 
    { 
     //fix 
    } 
    else 
    { 
     throw ex.InnerException; 
    } 
} 
+0

Neden 'is' anahtar sözcüğünü kullanmıyorsunuz? – Nick

+0

Kodunuz, orijinal ilk öneriyle işlevsel olarak farklı değildir ve kod için herhangi bir gerekçe veya gerekçe sunmadınız. –

1

Kişisel 2. kesinlikle ilginç bir çözümdür!

Gerçi dikkatli olmak istiyorsun

: ilk InnerException yakaladığında TargetInvocationException tipik başka bir bileşen tarafından atılmış olacak. Eğer throw ex.InnerException 'u kullanırsanız, içerdiği bazı bilgileri (yığın izleme gibi) yok edersiniz çünkü farklı bir konumdan yeniden atıyorsunuzdur.

Önerdiğiniz iki şeyden ötürü, kesinlikle # 1 ile gitmenizi öneririm. Yaptığın yapının içinde bir alternatifin farkında değilim. Ancak, InnerException başlangıçta başka bir yere atılmış olacak - bu hatayı halletmek için daha şık bir yer olup olmadığını araştırmaya değer, istisnanın atıldığı yere daha yakın.

İlgili konular