2012-04-20 10 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を表示する独自の方法があります。この目的のためにどの方法を呼びますか?私は非常に同じ文字列表現をプログラムで得ることができる方法はありますか?

は(Visual Studioの2010 Professionalでこれを試してみた。)

答えて

8

を自社のコアで、C#とVB.Net EEの使用の両方_ecvt_s機能を文字列にdoubleをフォーマットします。

両方のような表示よりC#とVBを作り、少しよりよいいくつかのコーナーケースを処理するために、結果として得られる文字列のクリーンアップの少しを行います。 _ecvt_s関数またはクリーンアップコードのいずれかが、表示される相違の原因となる可能性があります。一見するのが難しい

何人かは、この問題のすべてを、値の上にToStringと呼んで表示するのではなく、なぜこのようにするのかと尋ねるかもしれません。私たちがこれをしない理由はいくつかあります。

最初は、機能評価がToStringであっても、EEが実行できる最も高価なアクションです。一般的な実際のシナリオのプロファイルによれば、98%以上の時間が機能評価に費やされていました。パフォーマンスの影響があるため、私たちは機能評価を避けることができます。

第2の理由は、単に機能評価が常に利用できるとは限らないということです。 func evalが利用できない多くのケースがありますが、人々はまだdouble,intなどのプリミティブ型のディスプレイを見ることを期待しています。それらを取り除くと、基本的にデバッグの経験がなくなります。したがって、我々はToStringサポートなしでこの問題を解決する必要があります。

+0

非常に有益な答えです。しかし、実際に私の** ** ** _ecvt_s'がどのように呼び出されるのかは分かりません。そして私は 'ToString'メソッドも最終的に' _ecvt_s'を呼び出すことによって動作すると考えていますか?また、文字列に ".0"部分を追加するのはおそらくクリーンアップコードと呼ばれるもので行われるので、 'extern'メソッドを通して' _ecvt_s'を呼び出すだけでは、単独では動作しません。だから、おそらく答えは簡単です:いいえ、私はプログラム的に同じ文字列を取得することはできません? –

+0

@JeppeStigNielsenは、_ecvt_sがどのように呼び出されるかをあなたが何を意味するのかよく分かりません。あなたは詳しく説明できますか?まったく同じ文字列を取得する場合は、正確なクリーンアップコードがない限り、複製することは困難です。 – JaredPar

+0

'_ecvt_s'の出力がどのように' _SizeInBytes'や '_Count'のようなパラメータに依存するのかよくわかりません。しかし、VSで示される文字列は、常に小数点の右側に少なくとも1桁の数字が含まれているように見えますが、それ以外の文字は0になりません。彼らが「なぜ」をする理由。0 "のことは確かに' Int32'ではなく 'Double'であることをより明確にしています。 –

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

はこの答えを改善すること自由に感じなさいが。

関連する問題