デバッガでの表示内容はデフォルトだと情報量が少ない
C#でデバッグしているとき、
独自クラスのリストの要素を見ようとして
げんなりしたことはないでしょうか?
どの要素が何なのかさっぱり分からん…
デバッガでリストの中身を見たいとき。
それって大抵は何かバグを追いたいときですよね。
どんどん展開していけば一応中身は見られるのですが、
他のを見ようとしているうちに最初の方に見たものを忘れてしまうことも…。
「ローカル」ウィンドウなら開きっぱなしにできますが、
1つ1つ展開していくと縦に非常に長くなり一覧性が残念なことになります。
こんな状態ではデバッグの効率はがた落ちです。
生産性に影響が出てきます。
DebuggerDisplayAttributeで表示内容を差し替えられる
C#ではDebuggerDisplayAttributeを使うことで、
デバッガ上の表示を任意のものに差し替えられます。
たとえば、さっきの例がこんな感じになります。
各要素がなんなのか、分かりやすくなった!
使い方は、
クラス宣言の手前に[DebuggerDisplay(“表示したい内容”)]を付ける
これだけです。
次にコード例を示します。
using System.Diagnostics;
// {}(中括弧)でくくるとそのプロパティの値を表示
[DebuggerDisplay("Name = {Name}, Age = {Age}")]
public class ItemViewModel
{
public string Name { get; set; }
public int Age { get; set; }
}
こうするだけで、先ほどの画像のようになります。
DebuggerDisplayの構文は少々特殊で、
表示したいフィールド、プロパティの名前を{}(中括弧)で括ると、
実際の値を表示できます。
アクセスできる範囲はそのインスタンス変数に限られます。
ちなみに、実はToString()メソッドをオーバーライドすることでも、
表示内容を変えることができます。
public class ItemViewModel
{
public string Name { get; set; }
public int Age { get; set; }
// ToStringをオーバーライドしても同様の結果になるが、
// こちらはデバッガ以外の実挙動にも影響する可能性がある
public override string ToString()
{
return $"Name = {Name}, Age = {Age}";
}
}
ただし、ToStringメソッドは思わぬところで使われてたりするので、
できれば、アプリケーションの実挙動に影響を与えない、
DebuggerDisplayAttributeを使った方が良いです。
typoするとうまく表示されないのでnameofを使おう
ところで、プロパティ名を文字列で書いているのが気になりますね。
文字列で書いているとインテリセンスが働かないし、
typo(打ち間違い)していてもコンパイルエラーになりません。
タイポしている場合はうまく出てこなくなってしまいます。
プロパティ名を文字列で使うときはnameof演算子を使うことで、
すぐに間違いに気づけます。
nameof演算子については、別の記事があるので見てみてください。
nameofの使い道は?リファクタリングを助けるnameofを有効利用しよう!
ただし、アトリビュートでは$””による記法が使えないのがつらいところです。
+で繋ぐしかなくとても書きづらい上、
厳密にnameofを使っていこうとするとだいぶ横長になり、
コードの見通しが悪くなります…(以下の感じになります)
// 横に長くて見づらいし入力時もややこしい
[DebuggerDisplay("Name = {" + nameof(Name) + "}, Age = {" + nameof(Age) + "}")]
public class ItemViewModel
{
public string Name { get; set; }
public int Age { get; set; }
}
ぱっと見のコードの読みやすさとタイポのしにくさが、
現状だとトレードオフになってしまうのでお好みで良いと思います。
デバッグ時に初めてtypoに気づいたりするので、
私自身はなるべくnameof使う派
さらなるデバッグ表示のカスタマイズ
さらにデバッグ表示を凝りたい人は、
DebuggerBrowseableAttirubute, DebuggerTypeProxyAttribute
の活用を検討しても良いかもしれません。
DebuggerBrowseableAttributeを使うと、
「クラス内の特定のプロパティを表示しない」
といった設定ができます。
DebuggerTypeProxyAttributeを使うと
「表示内容すべてを別クラスに移譲する」
ことができます。
でも、デバッグのためにそこまでコストを払うべきかは微妙なところです。
さんさめは数年C#書いていますが、上記2つは使ったことがありません。
まとめ
本記事ではDebuggerDisplayAttributeについて紹介しました
- デバッガの表示内容はデフォルトだと情報量が少ない
- DebuggerDisplayAttributeを使うとデバッガでの表示内容を差し替えられる
- プロパティの中身を表示するには{}(中括弧)で括る
- nameofを併用するとtypoを防げていい感じ
- もっと作りこもうと思えばDebuggerBrowseable, DebuggerTypeProxy
なるものもあるが、そこまでしなくても良いかも。
クラスにはなるべくDebuggerDisplayAttributeをつけて、
快適なデバッグライフを送りましょう!
コメント