Exception.ToString() 的结果在不同的项目中是不同的
Result of Exception.ToString() is different in different projects
当我在我的测试控制台应用程序中创建嵌套异常时,我得到以下结果:
class Program
{
static void Main(string[] args)
{
var innerException = new SomeException("Inner Error");
var outerException = new Exception("Outer Error", innerException);
var outerExceptionString = outerException.ToString();
Console.WriteLine(outerExceptionString);
Console.ReadKey();
}
}
public class SomeException : Exception
{
public SomeException(string message) : base(message) { }
public SomeException(string message, Exception innerException) : base(message, innerException) { }
public override string ToString()
{
return "BLABLABLA";
}
}
输出:
System.Exception: Outer Error ---> BLABLABLA
--- End of inner exception stack trace ---
输出包含覆盖的字符串 "BLABLABLA"。但是,如果我现在将这段代码复制到我的 windows 应用程序中,我会得到不同的结果:
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
var innerException = new SomeException("Inner Error");
var outerException = new Exception("Outer Error", innerException);
var outerExceptionString = outerException.ToString();
MessageBox.Show(outerExceptionString);
// ... lots of other code
}
public class SomeException : Exception
{
public SomeException(string message) : base(message) { }
public SomeException(string message, Exception innerException) : base(message, innerException) { }
public override string ToString()
{
return "BLABLABLA";
}
}
输出:
System.Exception: Outer Error ---> TestUtility.SomeException: Inner Error
--- End of inner exception stack trace ---
如您所见,出于某种原因,它没有包含覆盖的字符串 "BLABLABLA"。我尝试在其他 windows 应用程序中对其进行测试,但结果与控制台应用程序中的结果相同。出于某种原因,我在一个特定项目中出现了不同的行为。有什么会影响异常格式化的方式吗?所有应用程序均使用 .net Framework 3.5。
您是否可能不小心从与预期不同的名称空间实例化了 class SomeException
?您的输出表明完全引用的类型是 TestUtility.SomeException
.
要对此进行测试,请在实例化时使用完全限定的命名空间 innerException
并查看其效果如何。
我发现了问题。尽管我使用的是相同的 3.5 .net 框架,但在运行时我的项目指向不同版本的 mscorlib.dll(出于某种原因)。 mscorlib 2.0 版本中的 Exception.cs 使输出具有覆盖的字符串,而在 mscorlib 4.0 中,代码似乎有所不同。
这是 mscorlib 2.0 版中的 Exception.ToString() 方法:
public override String ToString() {
String message = Message;
String s;
if (_className==null) {
_className = GetClassName();
}
if (message == null || message.Length <= 0) {
s = _className;
}
else {
s = _className + ": " + message;
}
if (_innerException!=null) {
s = s + " ---> " + _innerException.ToString() + Environment.NewLine + " " + Environment.GetResourceString("Exception_EndOfInnerExceptionStack");
}
if (StackTrace != null)
s += Environment.NewLine + StackTrace;
return s;
}
直接调用_innerException.ToString()。
但是这里是 mscorlib 4.0 版中的 Exception.ToString() 方法:
public override string ToString()
{
return this.ToString(true, true);
}
private string ToString(bool needFileLineInfo, bool needMessage)
{
string text = needMessage ? this.Message : null;
string text2;
if (text == null || text.Length <= 0)
{
text2 = this.GetClassName();
}
else
{
text2 = this.GetClassName() + ": " + text;
}
if (this._innerException != null)
{
text2 = string.Concat(new string[]
{
text2,
" ---> ",
this._innerException.ToString(needFileLineInfo, needMessage),
Environment.NewLine,
" ",
Environment.GetRuntimeResourceString("Exception_EndOfInnerExceptionStack")
});
}
string stackTrace = this.GetStackTrace(needFileLineInfo);
if (stackTrace != null)
{
text2 = text2 + Environment.NewLine + stackTrace;
}
return text2;
}
现在它调用一些重写方法 _innerException.ToString(bool, bool),这就是为什么它不包括 ToString() 的重写版本。我认为这会影响人们使用 ToString 覆盖的旧代码。我也不知道为什么在运行时我链接到不同的 dll 版本,即使我到处都将目标框架设置为 3.5,但这是一个不同的问题。
当我在我的测试控制台应用程序中创建嵌套异常时,我得到以下结果:
class Program
{
static void Main(string[] args)
{
var innerException = new SomeException("Inner Error");
var outerException = new Exception("Outer Error", innerException);
var outerExceptionString = outerException.ToString();
Console.WriteLine(outerExceptionString);
Console.ReadKey();
}
}
public class SomeException : Exception
{
public SomeException(string message) : base(message) { }
public SomeException(string message, Exception innerException) : base(message, innerException) { }
public override string ToString()
{
return "BLABLABLA";
}
}
输出:
System.Exception: Outer Error ---> BLABLABLA
--- End of inner exception stack trace ---
输出包含覆盖的字符串 "BLABLABLA"。但是,如果我现在将这段代码复制到我的 windows 应用程序中,我会得到不同的结果:
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
var innerException = new SomeException("Inner Error");
var outerException = new Exception("Outer Error", innerException);
var outerExceptionString = outerException.ToString();
MessageBox.Show(outerExceptionString);
// ... lots of other code
}
public class SomeException : Exception
{
public SomeException(string message) : base(message) { }
public SomeException(string message, Exception innerException) : base(message, innerException) { }
public override string ToString()
{
return "BLABLABLA";
}
}
输出:
System.Exception: Outer Error ---> TestUtility.SomeException: Inner Error
--- End of inner exception stack trace ---
如您所见,出于某种原因,它没有包含覆盖的字符串 "BLABLABLA"。我尝试在其他 windows 应用程序中对其进行测试,但结果与控制台应用程序中的结果相同。出于某种原因,我在一个特定项目中出现了不同的行为。有什么会影响异常格式化的方式吗?所有应用程序均使用 .net Framework 3.5。
您是否可能不小心从与预期不同的名称空间实例化了 class SomeException
?您的输出表明完全引用的类型是 TestUtility.SomeException
.
要对此进行测试,请在实例化时使用完全限定的命名空间 innerException
并查看其效果如何。
我发现了问题。尽管我使用的是相同的 3.5 .net 框架,但在运行时我的项目指向不同版本的 mscorlib.dll(出于某种原因)。 mscorlib 2.0 版本中的 Exception.cs 使输出具有覆盖的字符串,而在 mscorlib 4.0 中,代码似乎有所不同。
这是 mscorlib 2.0 版中的 Exception.ToString() 方法:
public override String ToString() {
String message = Message;
String s;
if (_className==null) {
_className = GetClassName();
}
if (message == null || message.Length <= 0) {
s = _className;
}
else {
s = _className + ": " + message;
}
if (_innerException!=null) {
s = s + " ---> " + _innerException.ToString() + Environment.NewLine + " " + Environment.GetResourceString("Exception_EndOfInnerExceptionStack");
}
if (StackTrace != null)
s += Environment.NewLine + StackTrace;
return s;
}
直接调用_innerException.ToString()。 但是这里是 mscorlib 4.0 版中的 Exception.ToString() 方法:
public override string ToString()
{
return this.ToString(true, true);
}
private string ToString(bool needFileLineInfo, bool needMessage)
{
string text = needMessage ? this.Message : null;
string text2;
if (text == null || text.Length <= 0)
{
text2 = this.GetClassName();
}
else
{
text2 = this.GetClassName() + ": " + text;
}
if (this._innerException != null)
{
text2 = string.Concat(new string[]
{
text2,
" ---> ",
this._innerException.ToString(needFileLineInfo, needMessage),
Environment.NewLine,
" ",
Environment.GetRuntimeResourceString("Exception_EndOfInnerExceptionStack")
});
}
string stackTrace = this.GetStackTrace(needFileLineInfo);
if (stackTrace != null)
{
text2 = text2 + Environment.NewLine + stackTrace;
}
return text2;
}
现在它调用一些重写方法 _innerException.ToString(bool, bool),这就是为什么它不包括 ToString() 的重写版本。我认为这会影响人们使用 ToString 覆盖的旧代码。我也不知道为什么在运行时我链接到不同的 dll 版本,即使我到处都将目标框架设置为 3.5,但这是一个不同的问题。