设置.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); } }
诀窍是获取实际的Exception
types的_innerException
字段,然后将内部exception值设置为您的类实例(本例中为MyException
)。
这也适用于variables。
Exception mainException = new Exception(); typeof(Exception) .GetField("_innerException", BindingFlags.NonPublic | BindingFlags.Instance) .SetValue(mainException , new Exception("Something bad happened!"));