捕获/修改(消息)/ Rethrow相同类型的exception

我想要一个中心位置从exception中提取信息,将所需的所有信息设置为其message参数,然后将该信息重新抛出为相同类型的exception。

更好的解决方案可能是在最终处理exception的地方执行此操作(并记录其消息),但是..我可以控制抛出exception的地方,而不是接收exception的地方记录其消息内容。

除了那个设计决定,并且假设该消息是一个只读属性,我会(?)以某种方式创建一个新的Exception对象,有没有办法使新的exception对象与原始exception对象的类型相同?

这是我的代码,它不能编译 – 它在throw行(我尝试动态转换对象)时偶然发现。

public static void RethrowExceptionWithFullDetailInMessage(string msg, Exception ex) { Exception curEx = ex; int cnt = 0; while (curEx != null) { msg += "\r\n"; msg += cnt++ + " ex.message: " + curEx.Message + "\r\n"; msg += "Stack: " + curEx.StackTrace; curEx = curEx.InnerException; } object newEx = Convert.ChangeType(new Exception(msg), ex.GetType()); throw (ex.GetType())newEx; } 

做这个

 throw (Exception)newEx; 

保留类型? (它汇编。)

Convert.ChangeType是否确保我得到了正确类型的exception?

你在这里想要做的并不像看起来那么容易,而且还有很多陷阱需要考虑。

请记住,Convert.ChangeType()会将一种类型转换为另一种类型(假设存在这样的路径,例如将字符串转换为int)。 大多数例外不会这样做(为什么会这样?)

为了解决此问题,您必须使用GetType()方法在运行时检查exception类型,并找到具有您可以满足的要求并调用它的构造函数。 这里要小心,因为您无法控制如何定义所有exception,因此无法保证您可以访问“标准”构造函数。

话虽这么说,如果你觉得自己是一个规则破坏者,你可以做这样的事……

 void Main() { try { throw new Exception("Bar"); } catch(Exception ex) { //I spit on the rules and change the message anyway ex.GetType().GetField("_message", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(ex, "Foo"); throw ex; } } 

您可以这样做以动态调用exception类型的构造函数:

 object newEx = Activator.CreateInstance(ex.GetType(), new object[] { msg }); 

您的原始代码将在运行时失败,因为对于Convert.ChangeType towork,exception类型必须实现IConvertible并支持转换为其他exception类型,我怀疑。

可能有点晚了,但这对你有用吗?

 catch (Exception ex) { throw new Exception("New message", ex); }