158

そのため、実行時に現在のオブジェクトの状態を表示するには、Visual Studio のイミディエイト ウィンドウが提供するものがとても気に入っています。シンプルにやってるだけ

? objectname

オブジェクトの適切にフォーマットされた「ダンプ」を提供します。

コードでこれを行う簡単な方法はありますか?ロギング時に同様のことを行うことができますか?

4

14 に答える 14

82

より大きなオブジェクト グラフの場合は、Json の使用を推奨しますが、戦略は少し異なります。最初に、呼び出しが簡単な静的クラスと、Json 変換をラップする静的メソッドを使用します (注: これを拡張メソッドにすることができます)。

using Newtonsoft.Json;

public static class F
{
    public static string Dump(object obj)
    {
        return JsonConvert.SerializeObject(obj);
    }
}

次に、あなたImmediate Window

var lookHere = F.Dump(myobj);

lookHere は、Locals先頭に $ が付加されたウィンドウに自動的に表示されます。または、ウォッチを追加することもできます。インスペクターの列の右側Valueには、横にドロップダウン キャレットがある虫眼鏡があります。ドロップダウン キャレットを選択し、Json ビジュアライザーを選択します。

Visual Studio 2013 ローカル ウィンドウのスクリーンショット

Visual Studio 2013 を使用しています。

于 2014-10-03T15:14:47.027 に答える
58

Linq サンプルに同梱されている ObjectDumper コードに基づいて何かを作成できます。サンプルを取得するに
は、この関連する質問の回答もご覧ください。

于 2008-12-11T18:07:45.403 に答える
34

Visual Studio Immediate Window を使用できます

これを貼り付けるだけです(actual明らかにオブジェクト名に変更してください):

Newtonsoft.Json.JsonConvert.SerializeObject(actual);

JSONでオブジェクトを出力する必要があります ここに画像の説明を入力

これを textmechanic テキスト ツールまたはメモ帳 ++にコピーして、エスケープされた引用符 ( \") を"改行 ( ) に置き換え、先頭と末尾から\r\n二重引用符 ( ) を削除し、読みやすくするためにjsbeautifierに貼り付けることができます。"

OPのコメントに更新

public static class Dumper
{
    public static void Dump(this object obj)
    {
        Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(obj)); // your logger
    }
}

これにより、任意のオブジェクトをダンプできるようになります。

これで時間が節約できることを願っています。

于 2015-06-23T10:01:40.950 に答える
27

これを行うにはもっと良い方法があると確信していますが、過去に次のような方法を使用して、ログに記録できる文字列にオブジェクトをシリアル化しました。

  private string ObjectToXml(object output)
  {
     string objectAsXmlString;

     System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(output.GetType());
     using (System.IO.StringWriter sw = new System.IO.StringWriter())
     {
        try
        {
           xs.Serialize(sw, output);
           objectAsXmlString = sw.ToString();
        }
        catch (Exception ex)
        {
           objectAsXmlString = ex.ToString();
        }
     }

     return objectAsXmlString;
  }

メソッドがシリアル化されたオブジェクトではなく例外を返す場合もあるため、ログに記録するオブジェクトがシリアル化可能であることを確認する必要があります。

于 2008-12-11T18:08:54.140 に答える
19

ServiceStack.Textには、これを正確に実行するT.Dump()拡張メソッドがあり、あらゆるタイプのすべてのプロパティを読みやすい形式で再帰的にダンプします。

使用例:

var model = new TestModel();
Console.WriteLine(model.Dump());

および出力:

{
    Int: 1,
    String: One,
    DateTime: 2010-04-11,
    Guid: c050437f6fcd46be9b2d0806a0860b3e,
    EmptyIntList: [],
    IntList:
    [
        1,
        2,
        3
    ],
    StringList:
    [
        one,
        two,
        three
    ],
    StringIntMap:
    {
        a: 1,
        b: 2,
        c: 3
    }
}
于 2010-08-18T16:04:34.090 に答える
17

以下は、適切にフォーマットされたフラット オブジェクトを作成するためのばかばかしいほど単純な方法です。

using Newtonsoft.Json.Linq;

Debug.WriteLine("The object is " + JObject.FromObject(theObjectToDump).ToString());

何が起こっているかというと、オブジェクトは最初に によって JSON 内部表現にJObject.FromObject変換され、次に によって JSON 文字列に変換されますToString。(そしてもちろん、JSON 文字列は、特に改行とインデントを含むため、単純なオブジェクトの非常に優れた表現ですToString。) 「ToString」はもちろん関係ありません (+文字列とオブジェクトを連結するために使用することで暗示されているため)。ここで指定するのが好きです。

于 2014-06-10T21:08:11.407 に答える
4

私が好きなことは、ToString() をオーバーライドして、型名を超えてより有用な出力を取得することです。これはデバッガーで便利です。オブジェクトを展開しなくても、オブジェクトについて必要な情報を表示できます。

于 2008-12-11T19:05:22.980 に答える
4

リフレクションを使用してすべてのオブジェクト プロパティをループし、それらの値を取得してログに保存できます。書式設定は非常に簡単です (オブジェクトのプロパティとその値をインデントするために \t を使用できます):

MyObject
    Property1 = value
    Property2 = value2
    OtherObject
       OtherProperty = value ...
于 2008-12-11T18:05:35.363 に答える
2

独自の WriteLine メソッドを作成できます-

public static void WriteLine<T>(T obj)
    {
        var t = typeof(T);
        var props = t.GetProperties();
        StringBuilder sb = new StringBuilder();
        foreach (var item in props)
        {
            sb.Append($"{item.Name}:{item.GetValue(obj,null)}; ");
        }
        sb.AppendLine();
        Console.WriteLine(sb.ToString());
    }

次のように使用します-

WriteLine(myObject);

使用できるコレクションを作成するには-

 var ifaces = t.GetInterfaces();
        if (ifaces.Any(o => o.Name.StartsWith("ICollection")))
        {

            dynamic lst = t.GetMethod("GetEnumerator").Invoke(obj, null);
            while (lst.MoveNext())
            {
                WriteLine(lst.Current);
            }
        }   

メソッドは次のようになります-

 public static void WriteLine<T>(T obj)
    {
        var t = typeof(T);
        var ifaces = t.GetInterfaces();
        if (ifaces.Any(o => o.Name.StartsWith("ICollection")))
        {

            dynamic lst = t.GetMethod("GetEnumerator").Invoke(obj, null);
            while (lst.MoveNext())
            {
                WriteLine(lst.Current);
            }
        }            
        else if (t.GetProperties().Any())
        {
            var props = t.GetProperties();
            StringBuilder sb = new StringBuilder();
            foreach (var item in props)
            {
                sb.Append($"{item.Name}:{item.GetValue(obj, null)}; ");
            }
            sb.AppendLine();
            Console.WriteLine(sb.ToString());
        }
    }

if, else ifこのようにインターフェイス、属性、基本型などと再帰 (これは再帰的な方法であるため) を使用してチェックすると、オブジェクト ダンパーを実現できますが、確かに面倒です。Microsoft の LINQ Sample のオブジェクト ダンパーを使用すると、時間を節約できます。

于 2016-02-26T17:45:50.027 に答える