当我在做一个项目时,我想我自己:“嗯,记录一条消息会非常方便,然后用同样的消息抛出一个异常。由于这会让我保留我的“例外情况是出于特殊情况”原则,但仍然确保我们记录有关系统中出现问题的详细信息。CLR在'throw'上做了什么?
这样就产生了:
public static class LogAndThrow
{
public static void Message<TException>(string message) where TException : Exception
{
// Log message here
var constructor =
typeof(TException).GetConstructor(new[] { typeof(string) });
throw (TException)constructor.Invoke(new[] { message });
}
}
相信这是一个有点粗糙(我剪下来的这个帖子),但它的作品。
然而,作为通过反射来构建异常的人的类型,我很烦恼堆栈跟踪会被LogAndThrow.Message()行“污染”。
所以我掀起来修复:-)
我能够与一些系列化和其他弄虚作假,都非常愚蠢和力量,以取代堆栈跟踪。但我想知道这一点,因为。
但我注意到了一些好奇:
var exception = new Exception();
throw exception;
创建该异常后,却抛出之前,唯一集消息。堆栈跟踪等是空的。
以上是等同于以下IL:
.locals init (
[0] class [mscorlib]System.Exception exception)
nop
newobj instance void [mscorlib]System.Exception::.ctor()
stloc.0
ldloc.0
throw
这似乎对我来说,IL为“扔”在做一些事情不仅仅是采取这一参考,并走它的堆栈更多。
有没有人知道当IL'throw'到达时,运行时正在执行堆栈上的异常吗?
我们将在下面用来改变堆栈中抛出涉及“神奇”的诀窍,我认为:
此代码是可怕的和错误的。更多的科学实验比任何应该永远放在evereververEVER
var e = new Exception("message here");
try
{
throw e;
}
finally
{
// Get the private file _stackTraceString with reflection
field.SetValue(e, new StackTrace(1).ToString());
}
为什么在'catch'中通过'throw e;'重新抛出异常是不好的 - 它会修改关于对象中堆栈跟踪的属性。 – IllidanS4 2016-12-01 21:17:57