デバッグ時のエラーログ出力などで、呼び出し元の情報や、スタックフレームの情報を出力したい事があると思う。
そんなときの方法。
環境
Windows10 pro 64bit
Visual Suodio 2019
.Net Fremework 4.8
Windows フォームアプリケーション(.NET Fremework)
呼び出し元情報の取得
System.Runtime.CompilerServices.CallerMemberNameAttribute
System.Runtime.CompilerServices.CallerFilePathAttribute
System.Runtime.CompilerServices.CallerLineNumberAttribute
を使った呼び出し元の、メンバー名、ファイルパス、ソース内行数の取得方法。
using System.Runtime.CompilerServices;
public static void ErrLog( string str,
[CallerMemberName] string name = "",
[CallerFilePath] string path = "",
[CallerLineNumber] int line = 0)
{
Console.WriteLine(str);
Console.WriteLine($"{path}({line}) {name}");
}
private void Form1_Load(object sender, EventArgs e)
{
ErrLog("エラーログですよ。");
}
出力結果。ちゃんと取得できた。
エラーログですよ。 G:\AmaryllisProjects\Amaryllis\Test\TestForm.cs(133) Form1_Load
ちなみに、Visual Stdio の出力ウィンドウに出力された「ファイルパス(行数) 」から始まるログを ダブルクリックするとジャンプできる。
スタックフレーム情報の取得
using System.Diagnostics;
public static void ErrLogSF(string str)
{
string stack = "";
for(int i = 0; i < 256; i++)
{
var stackFrame = new StackFrame(i, true);
if(stackFrame != null && !string.IsNullOrEmpty(stackFrame.GetFileName()) && 1 <= stackFrame.GetFileLineNumber())
{
stack += $"\r\n{stackFrame.GetFileName()}({stackFrame.GetFileLineNumber()}) {stackFrame.GetMethod().Name}";
}
else
{
break;
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
ErrLog("エラーログですよ。");
}
出力結果。
エラーログですよ。 G:\AmaryllisProjects\Amaryllis\Test\TestForm.cs(137) ErrLogSF G:\AmaryllisProjects\Amaryllis\Test\TestForm.cs(163) Form1_Load
※注意
スタックフレームを使用する場合は .pdb ファイルがないと機能しない。
.pdb の出力設定は プロジェクトのプロパティ ー ビルド ー 詳細 ー デバッグ情報 にある。