我正在使用一个使用Exception.ToString()报告异常的测试框架。
我昨天遇到了嵌套异常的不完整报告,并且在使用Reflector进行了一些工作后得出的结论是.NET 4.0已经打破了内部异常字符串表示的组成方式。
这是一个例子;
public class MyException : Exception
{
DateTime when;
public MyException(DateTime when)
{
this.when = when;
}
public override string ToString()
{
var builder = new StringBuilder();
builder.AppendFormat("Happened at: {0}\r\n", this.when);
builder.Append(base.ToString());
return builder.ToString();
}
}
class Program
{
private static void throws()
{
throw new Exception("bobby!", new MyException(DateTime.Now));
}
private static void catches()
{
try
{
throws();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
static void Main(string[] args)
{
catches();
}
}
此处的控制台输出不包含我的自定义“Happened at”前缀。
请注意,如果我们直接抛出MyException,而不是嵌套在另一个异常中,则将使用自定义字符串rep。
事实证明,Exception.ToString()不再调用内部异常的ToString(),而是私有方法ToString(bool),即
// Exception
public override string ToString()
{
return this.ToString(true);
}
private string ToString(bool needFileLineInfo)
{
// yada yada
if (this._innerException != null)
{
result += "some stuff " + this._innerException.ToString(needFileLineInfo) + " some more stuff";
^^^^^^^^^^^^^^^^^^^^^^^^^^
}
// yada yada
return result;
}
因此,由于Exception.ToString()不再调用内部异常的ToString(),实现已经为内部异常的任何自定义字符串表示的机会短路。
在.NET 2.0中,可覆盖的ToString()按预期调用,因此这是一个突破性的变化。
文档没有改变,仍然声称;
ToString的默认实现获取类的名称 抛出当前异常,消息,调用的结果 内部异常[...]
上的ToString
http://msdn.microsoft.com/en-us/library/system.exception.tostring.aspx
除了我以外,这对任何人来说听起来都像个错误吗?