2012-04-20 26 views
7

Hãy thử gỡ lỗi chương trình đơn giản sau đây và di chuột qua x trong mỗi bước (hoặc "Thêm Xem" cho x hoặc bất kỳ thứ gì).Visual Studio hiển thị System.Double khi gỡ lỗi như thế nào?

using System; 
using System.Globalization; 

static class Program 
{ 
    static double x; 

    static void Main() 
    { 
    x = 2d; 

    // now debugger shows "2.0", as if it has used 
    // x.ToString("F1", CultureInfo.InvariantCulture) 

    x = 8.0/7.0; 

    // now debugger shows "1.1428571428571428", as if it had used 
    // x.ToString("R", CultureInfo.InvariantCulture) 
    // Note that 17 significant figures are shown, not the usual 15. 

    x = -1e-200/1e200; 

    // now debugger shows "0.0"; there is no indication that this is really negative zero 
    // 

    Console.WriteLine(1.0/x); // this is negative infinity 
    } 
} 

Vì vậy, dường như VS có cách riêng để hiển thị System.Double. Phương thức nào nó gọi cho mục đích này? Có cách nào tôi có thể nhận được cùng một chuỗi đại diện lập trình?

(Cố gắng này ra với Visual Studio 2010 Professional.)

Trả lời

8

Tại cốt lõi của họ cả C# và sử dụng VB.Net EE của các _ecvt_s chức năng để định dạng một double thành một chuỗi.

Cả hai làm một chút dọn dẹp vào chuỗi kết quả để làm cho màn hình hơn C# và VB thích và xử lý một số trường hợp góc một chút đẹp hơn. Hoặc chức năng _ecvt_s hoặc mã dọn dẹp có thể chịu trách nhiệm về sự khác biệt mà bạn thấy. Khó có thể nói rõ:

Một số người có thể hỏi lý do tại sao chúng tôi sẽ trải qua tất cả sự cố này thay vì chỉ nói ToString về giá trị và hiển thị điều đó. Có một vài lý do chúng tôi không làm điều này.

Thứ nhất chỉ đơn giản là đánh giá chức năng, thậm chí ToString, là hành động đắt nhất duy nhất mà EE có thể thực hiện. Hồ sơ của các tình huống thực tế phổ biến cho thấy rằng hơn 98% thời gian của chúng tôi đã được chi cho việc đánh giá chức năng. Bất cứ lúc nào chúng ta có thể tránh một func eval chúng tôi làm vì những tác động hiệu suất.

Lý do thứ hai chỉ đơn giản là đánh giá chức năng không phải lúc nào cũng có sẵn. Có một số trường hợp func eval không khả dụng nhưng mọi người vẫn mong đợi để xem hiển thị cho các kiểu nguyên thủy như double, int, v.v ... Lấy chúng đi về cơ bản sẽ giết trải nghiệm gỡ lỗi. Do đó chúng tôi cần giải quyết vấn đề này mà không cần hỗ trợ ToString.

+0

Câu trả lời rất có nhiều thông tin. Nhưng nó không thực sự nói với ** của tôi như thế nào ** '_ecvt_s' được gọi là. Và tôi nghi ngờ rằng các phương thức 'ToString' cũng hoạt động bằng cách cuối cùng gọi' _ecvt_s'? Ngoài ra, thêm phần ".0" vào chuỗi có thể được thực hiện bởi những gì bạn gọi là mã dọn dẹp, vì vậy tôi gọi '_ecvt_s' thông qua một số phương thức' extern' sẽ không thực hiện công việc một mình. Vì vậy, có lẽ câu trả lời chỉ đơn giản là: Không, tôi không thể nhận được cùng một chuỗi chương trình? –

+0

@JeppeStigNielsen không hoàn toàn chắc chắn ý bạn là gì khi gọi _ecvt_s. Bạn có thể xây dựng? Để nhận được chính xác cùng một chuỗi chính mình, có rất khó để nhân rộng, trừ khi bạn có mã dọn dẹp chính xác tiện dụng. – JaredPar

+0

Tôi không chắc đầu ra của '_ecvt_s' phụ thuộc vào các tham số như' _SizeInBytes' và '_Count' như thế nào. Nhưng chuỗi được hiển thị bởi VS dường như luôn bao gồm ít nhất một chữ số ở bên phải dấu thập phân, nhưng các đường khác không có dấu 0. Lý do tại sao họ làm ".0 "điều chắc chắn là nó làm cho nó rõ ràng hơn rằng nó không phải là một' Int32' nhưng một 'Double'. –

1

Tôi sẽ chấp nhận câu trả lời của JaredPar vì nó mô tả cách mọi thứ hoạt động bên trong trình gỡ rối.

Nhưng vì câu trả lời không giúp để có được chuỗi cùng, đây là một số mã thường (luôn?) Cung cấp cho các chuỗi giống nhau:

static string ToDebugString(this double d) 
{ 
    if (Double.IsNaN(d) || Double.IsInfinity(d)) 
    return d.ToString(CultureInfo.InvariantCulture); 

    string s = d.ToString("R", CultureInfo.InvariantCulture); 
    if (!s.Contains(".")) 
    s += ".0"; 
    return s; 
} 

Xin vui lòng để cải thiện câu trả lời này.

Các vấn đề liên quan