如何从嵌套的try-catch块中重新抛出先前的exception? (C#)

我有尝试类型转换的代码。 如果失败,我想尝试别的东西,如果失败,则重新抛出第一次转换尝试的原始exception。 问题是,我知道重新抛出的唯一方法就是“ throw; ‘坐在拦截区的尽头。 当我只希望从另一个catch块中发生重新抛出时会发生什么?

 try { valueFromData = Convert.ChangeType(valueFromData, pi.PropertyType); } catch(InvalidCastException e) { Debug.WriteLine(String.Concat("Info - Direct conversion failed. Attempting to convert using String as an intermidiate type.")); try { valueFromData = Convert.ChangeType(valueFromData.ToString(), pi.PropertyType); } catch { throw e; } } 

如上所示,我必须使用’ throw e; ‘,它会重置调用堆栈。

到目前为止我唯一的解决方法是(imo)粗略:

 bool handled = true; ... catch { handled = false; } if( !handled ) throw; 

无法从内部catch块内的外部catch块重新抛出exception。 实现此模式的最佳方法是注意内部操作是否成功

 catch (InvalidCastException e) { bool threw = false; try { ... } catch { threw = true; } if (threw) { throw; } } 

如果您打算多次尝试转换,那么在适用的情况下使用非投掷操作肯定是有意义的,这样您就可以完全回避问题。

假设为了论证而不可能,下一步是质疑throw e; 做法。 在你提供的示例代码中,如果你的throw重置了调用堆栈,恕我直言就没有任何问题。 一旦有人获得此方法的源代码(修改后的调用堆栈仍将指向该代码),我认为很明显发生了什么。 因此,重置调用堆栈总是一个值得怀疑的决定, 在这种特殊情况下应该允许它发生,因为没有明显的缺点。

最后,你提到的解决方法既有趣又有意义(同意!)。

我尝试了以下内容,它似乎达到了你的目标,当第二个exception发生时(在这种情况下, ArgumentException )它抛出第一个exception( InvalidCastException

 [TestMethod] [ExpectedException(typeof(InvalidCastException))] public void ReThrowException() { var ret = false; try { ret = F1(1); } catch (InvalidCastException ex) { try { ret = F1(2); } catch (Exception e) { Debug.WriteLine(e.Message); throw ex; } } } private bool F1(int i) { if (i == 1) { throw new InvalidCastException(); } else { throw new ArgumentException(); } return false; } 

希望这可以帮助,

艾伦。