在.NET 4.0中,Exception.ToString被破坏了吗?

Kim*_*man 5 .net exception

我正在使用一个使用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();
  }
}
Run Code Online (Sandbox Code Playgroud)

此处的控制台输出包含我的自定义"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;
}
Run Code Online (Sandbox Code Playgroud)

因此,由于Exception.ToString()不再调用内部异常的ToString(),因此实现已将内部异常的自定义字符串表示的任何机会短路.

在.NET 2.0中,可覆盖的ToString()被按预期调用,因此这是一个突破性的变化.

文档没有改变,仍然声称;

ToString的默认实现获取抛出当前异常的类的名称,消息,在内部异常[...]上调用ToString的结果

http://msdn.microsoft.com/en-us/library/system.exception.tostring.aspx

除了我之外,这对任何人来说听起来都像个错误吗

Pat*_*tko 7

是的,它似乎是一个错误.看看MS Connect问题.