设置.NETexception对象的InnerException

我如何设置Exception对象的InnerException属性,而我在该对象的构造函数? 这归结为查找和设置没有setter的属性的后台字段。

顺便说一句:我已经看到这个( http://evain.net/blog/articles/2009/05/01/getting-the-field-backing-a-property-using-reflection ),但寻找非基于IL的解决scheme,如果可能的话。

Exception构造函数是创buildExceptiontypes的地方,所以我不能使用基类构造函数MyException():base(…)来调用它。

为什么你不能只调用以InnerException作为参数的构造函数呢? 如果由于某种原因,这是不可能的,System.Exception中的后台字段是:

 private Exception _innerException; 

我用Redgate的Reflectorfind了它。 使用reflection,我想你可以设置内部的exception。

编辑:在大多数情况下,通过reflection来访问私人领域并不是一个好主意,但是我对NT的情况还不了解,不知道是好还是坏的想法。

通过调用base ctor来设置内部exception:

 public MyException(string message, Exception innerException) : base(message, innerException) {...} 

如果您需要运行一些代码来获取exception,请使用静态方法:

 public MyException(SomeData data) : base(GetMessage(data), GetInner(data)) {...} static Exception GetInner(SomeData data) {...} // <===== your type creation here! static string GetMessage(SomeData data) {...} 

Exception类有一个重载的构造函数接受内部exception作为参数:

 Exception exc = new Exception("message", new Exception("inner message")); 

这是你想要的?

 Exception exceptionWithMoreInfo = new Exception("extra info", ex); 

假设你已经在冒泡之前收集了一个你想要添加更多信息的exception,这是正常的做法。

当使用Exception(string, Exception)构造函数时是不是应该设置InnerException ? 我认为这是devise,否则你不能改变,否则你总是可以在施工时推迟到相应的构造函数:

 class MyException : Exception { public MyException() : base("foo", new Exception("bar")) { ... } ... } 

我认为你不应该打破你的代码中的exception链,因为这通常会导致错误,你永远不会再find。

如果我理解你的问题,你想要做这样的事情:

 Exception ex = new Exception("test"); Exception innerEx = new Exception("inner"); ex.GetType().GetField("_innerException", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(ex, innerEx); 

如果你在一个从Exceptioninheritance的对象的构造函数中,你会用this来代替第一个ex

但是,这可能不是处理你正在处理的任何事情的最好方式。

使用Redgate的reflection器find字段。 我怀疑exception实现将会改变…但是这是一个风险!

我知道我真的很晚参加派对,但是我觉得这很有效。

 public class MyException: Exception { public void SetInnerException(Exception exception) { typeof(Exception) .GetField("_innerException", BindingFlags.NonPublic | BindingFlags.Instance) .SetValue(this, exception); } } 

诀窍是获取实际的Exceptiontypes的_innerException字段,然后将内部exception值设置为您的类实例(本例中为MyException )。

这也适用于variables。

 Exception mainException = new Exception(); typeof(Exception) .GetField("_innerException", BindingFlags.NonPublic | BindingFlags.Instance) .SetValue(mainException , new Exception("Something bad happened!"));