web-dev-qa-db-ja.com

C#-例外をスローした行番号を取得

catchブロックで、例外をスローした行番号を取得するにはどうすればよいですか?

172
MBZ

Exception.StackTraceから取得したフォーマット済みのスタックトレース以外の行番号が必要な場合は、 StackTrace クラスを使用できます。

try
{
    throw new Exception();
}
catch (Exception ex)
{
    // Get stack trace for the exception with source file information
    var st = new StackTrace(ex, true);
    // Get the top stack frame
    var frame = st.GetFrame(0);
    // Get the line number from the stack frame
    var line = frame.GetFileLineNumber();
}

これは、アセンブリで使用可能なpdbファイルがある場合にのみ機能することに注意してください。

243
Quartermeister

簡単な方法、Exception.ToString()関数を使用すると、例外の説明の後に行が返されます。

また、アプリケーション全体に関するデバッグ情報/ログが含まれているため、プログラムデバッグデータベースを確認することもできます。

55

.PBOファイルがない場合:

C#

public int GetLineNumber(Exception ex)
{
    var lineNumber = 0;
    const string lineSearch = ":line ";
    var index = ex.StackTrace.LastIndexOf(lineSearch);
    if (index != -1)
    {
        var lineNumberText = ex.StackTrace.Substring(index + lineSearch.Length);
        if (int.TryParse(lineNumberText, out lineNumber))
        {
        }
    }
    return lineNumber;
}

Vb.net

Public Function GetLineNumber(ByVal ex As Exception)
    Dim lineNumber As Int32 = 0
    Const lineSearch As String = ":line "
    Dim index = ex.StackTrace.LastIndexOf(lineSearch)
    If index <> -1 Then
        Dim lineNumberText = ex.StackTrace.Substring(index + lineSearch.Length)
        If Int32.TryParse(lineNumberText, lineNumber) Then
        End If
    End If
    Return lineNumber
End Function

または、Exceptionクラスの拡張として

public static class MyExtensions
{
    public static int LineNumber(this Exception ex)
    {
        var lineNumber = 0;
        const string lineSearch = ":line ";
        var index = ex.StackTrace.LastIndexOf(lineSearch);
        if (index != -1)
        {
            var lineNumberText = ex.StackTrace.Substring(index + lineSearch.Length);
            if (int.TryParse(lineNumberText, out lineNumber))
            {
            }
        }
        return lineNumber;
    }
}   
25
radbyx

メタデータ情報を含むアセンブリに関連付けられた.PDBシンボルファイルを含めることができ、例外がスローされると、この例外が発生した場所のスタックトレースに完全な情報が含まれます。スタック内の各メソッドの行番号が含まれます。

17
Darin Dimitrov

できます:

var LineNumber = new StackTrace(ex, True).GetFrame(0).GetFileLineNumber();

これをチェック

StackTrace st = new StackTrace(ex, true);
//Get the first stack frame
StackFrame frame = st.GetFrame(0);

//Get the file name
string fileName = frame.GetFileName();

//Get the method name
string methodName = frame.GetMethod().Name;

//Get the line number from the stack frame
int line = frame.GetFileLineNumber();

//Get the column number
int col = frame.GetFileColumnNumber();
2
Ram Maurya

@ davy-cのソリューションを使用しようとしましたが、例外「System.FormatException: '入力文字列が正しい形式ではありませんでした。」が発生しました。投稿して思いついた:

int line = Convert.ToInt32(objErr.ToString().Substring(objErr.ToString().IndexOf("line")).Substring(0, objErr.ToString().Substring(objErr.ToString().IndexOf("line")).ToString().IndexOf("\r\n")).Replace("line ", ""));

これはVS2017 C#で機能します。

1
Joseph Michael

回答の更新

    // Get stack trace for the exception with source file information
    var st = new StackTrace(ex, true);
    // Get the top stack frame
    var frame = st.GetFrame(st.FrameCount-1);
    // Get the line number from the stack frame
    var line = frame.GetFileLineNumber();
1
Sean Fleming

拡張方法

static class ExceptionHelpers
{
    public static int LineNumber(this Exception ex)
    {
        int n;
        int i = ex.StackTrace.LastIndexOf(" ");
        if (i > -1)
        {
            string s = ex.StackTrace.Substring(i + 1);
            if (int.TryParse(s, out n))
                return n;
        }
        return -1;
    }
}

使用法

try
{
    throw new Exception("A new error happened");
}
catch (Exception ex)
{
    //If error in exception LineNumber() will be -1
    System.Diagnostics.Debug.WriteLine("[" + ex.LineNumber() + "] " + ex.Message);
}
0
Arvo Bowen