2012-11-09 29 views
5

Tôi đang sử dụng khung kiểm tra báo cáo ngoại lệ bằng cách sử dụng Exception.ToString().Exception.ToString bị hỏng trong .NET 4.0?

Tôi chạy vào báo cáo không đầy đủ các ngoại lệ lồng nhau ngày hôm qua và sau khi một số công việc với Reflector đi đến kết luận rằng .NET 4.0 đã phá vỡ cách biểu diễn chuỗi bên trong ngoại lệ.

Đây là một ví dụ;

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(); 
    } 
} 

Giao diện điều khiển đầu ra ở đây sẽ không chứa tùy chỉnh của tôi "Xảy Ra Tại" tiền tố.

Lưu ý rằng nếu chúng ta ném trực tiếp MyException, không được lồng trong một ngoại lệ khác, đại diện chuỗi tùy chỉnh sẽ được sử dụng.

Hóa ra lý do là Exception.ToString() không còn gọi ToString ngoại trừ bên trong của(), mà là một phương pháp riêng, ToString (bool), tức là

// 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; 
} 

Vì vậy, kể từ khi ngoại lệ. ToString() không còn gọi hàm ToString() của ngoại lệ bên trong nữa, việc thực thi đã rút ngắn bất kỳ cơ hội nào của các biểu diễn chuỗi tùy chỉnh cho các ngoại lệ bên trong.

Trong .NET 2.0, ToString() được gọi là quá mức được gọi là mong đợi, vì vậy đây là một thay đổi đột phá ở đâu đó trên đường đi.

Tài liệu chưa thay đổi và vẫn tuyên bố rằng;

Việc thực hiện mặc định của ToString lấy tên của lớp mà ném ngoại lệ hiện hành, thông báo, kết quả của gọi ToString ngày ngoại trừ bên trong [...]

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

Điều này có vẻ giống như một lỗi đối với bất kỳ ai trừ tôi không?

+1

Không giải quyết lưu ý nhỏ về xe buýt vấn đề của bạn, bạn không nên lấy được lớp học của mình từ Ngoại lệ, xuất phát từ: ApplicationException. - http://blog.gurock.com/articles/creating-custom-exceptions-in-dotnet –

+1

Cảm ơn! Ví dụ đã thay đổi để không đánh lạc hướng những người khác :-) –

+6

Về 'ApplicationException' so với' Ngoại lệ ', hướng dẫn là ** không ** sử dụng 'ApplicationException'. Tham khảo: http://stackoverflow.com/a/52770/66849 – PHeiberg

Trả lời

7

Có, nó có vẻ là một lỗi. Hãy xem MS Connect issue.

+0

Cảm ơn bạn! Tôi đã dành rất nhiều thời gian để tìm kiếm Kết nối ngày hôm qua và không thể tìm thấy bất kỳ thứ gì có liên quan. Bây giờ tôi sẽ chỉ nín thở cho đến khi bản phát hành chính tiếp theo xuất hiện :-) –

+0

Nhân tiện, có ai có môi trường .NET 4.5 mà họ có thể kiểm tra điều này không? Vấn đề đã được đóng vào tháng 9 năm 2010, vì vậy nó cảm thấy như thế này nên đã làm cho nó thành 4.5 ... Cảm ơn! –

+1

Thật không may, điều này không được sửa trong .NET 4.5. Bạn cũng có thể tải xuống mã nguồn từ http://referencesource.microsoft.com/netframework.aspx và tự kiểm tra.Vì vậy, nếu bạn thực sự có ý định giữ hơi thở của bạn .. biết bạn :) – Patko