2012-04-20 57 views
7

嘗試調試下面的簡單程序,並將鼠標放在每個步驟中的x(或「添加監視」爲x或其他)。Visual Studio在調試過程中如何顯示System.Double?

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

所以,顯然VS都有自己的方式來顯示System.Double。哪種方法需要這個目的?有沒有一種方法可以通過編程獲得相同的字符串表示?

回答

8

(與Visual Studio 2010專業版。試過了這一點),其核心無論是C#和VB.Net EE的使用_ecvt_s功能格式化double爲一個字符串。

兩個做的結果字符串清理一點點,使顯示效果更加C#和VB等,並處理一些極端情況更好一點。 _ecvt_s函數或清理代碼可能會導致您看到的差異。難以一目瞭然

有人可能會問,爲什麼我們會經歷所有這些麻煩,而不是說只是調用ToString的價值和顯示。有幾個原因我們不這樣做。

第一個很簡單的功能評估,即使是ToString,也是EE可以採取的最昂貴的行動。常見的真實情景分析表明,我們有超過98%的時間用於功能評估。任何時候我們都可以避免由於性能影響而做的功能。

第二個原因很簡單,功能評估並不總是可用的。有很多情況下func eval不可用,但人們仍然期望看到原始類型的顯示,如double,int等等。將它們拿走將基本上消除調試體驗。因此我們需要在不支持ToString的情況下解決這個問題。

+0

非常豐富的答案。但它並沒有真正告訴我**如何調用''''''''''''''''''''。我懷疑'ToString'方法也可以通過調用'_ecvt_s'來工作?另外,爲字符串添加「.0」部分可能是通過你所謂的清理代碼完成的,所以我通過某種「extern」方法調用'_ecvt_s'不會單獨完成這項工作。所以也許答案很簡單:不,我不能以編程方式獲得相同的字符串? – 2012-04-25 15:53:37

+0

@JeppeStigNielsen不太清楚你調用_ecvt_s的含義。你能詳細說明一下嗎?至於自己得到完全相同的字符串,是的,除非您有方便的確切清理代碼,否則很難複製。 – JaredPar 2012-04-25 16:36:45

+0

我不知道'_ecvt_s'的輸出如何依賴於參數,比如'_SizeInBytes'和'_Count'。但由VS顯示的字符串似乎總是包含小數點右側的至少一位數字,但其他字段沒有尾隨零。他們之所以這樣做「。0「的意思是,它更清楚地表明它不是'Int32',而是'Double'。 – 2012-04-25 17:25:32

1

我會接受JaredPar的回答,因爲它描述了調試器內部的工作方式。

但因爲回答不利於獲得相同的字符串,這裏是一些代碼,通常(總是?)給出了相同的字符串:

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

請隨意提高這個答案。

相關問題