Exception.ToString()的结果在不同的项目中是不同的

本文关键字:项目 是不同 结果 ToString Exception | 更新日期: 2024-10-22 21:16:36

当我在测试控制台应用程序中创建嵌套异常时,我得到以下结果:

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。

Exception.ToString()的结果在不同的项目中是不同的

我发现了问题。尽管我使用的是相同的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,但这是一个不同的问题。

是否可能意外地从与预期不同的命名空间实例化了类SomeException?您的输出表明完全引用的类型是TestUtility.SomeException

为了测试这一点,在实例化innerException时使用一个完全限定的命名空间,看看它是如何为您工作的。

相关文章: