現在の行番号を取得するにはどうすればよいですか?


117

これが私がしたいことの例です:

MessageBox.Show("Error line number " + CurrentLineNumber);

上のCurrentLineNumberコードでは、このコードのソースコードの行番号を指定する必要があります。

どうやってやるの?


JITコンパイラーが最適化(コードのインライン化など)を行う可能があるため、これを確実に行うことはできません。つまり、行番号が間違っています。
adrianbanks 2012

1
必要に応じて最適化をオフにできるため、これ確実に行うことができます。
jwg 2013

回答:


175

.NET 4.5 / C#5では、新しい呼び出し元の属性を使用するユーティリティメソッドを記述することで、コンパイラーにこの作業を実行させることができます。

static void SomeMethodSomewhere()
{
    ShowMessage("Boo");
}
...
static void ShowMessage(string message,
    [CallerLineNumber] int lineNumber = 0,
    [CallerMemberName] string caller = null)
{
     MessageBox.Show(message + " at line " + lineNumber + " (" + caller + ")");
}

たとえば、次のように表示されます。

39行目のブー(SomeMethodSomewhere)

[CallerFilePath]元のコードファイルのパスを通知するものもあります。


答えてくれてありがとう オブジェクト名も学ぶことは可能ですか?ああ、私は何か他のものと混同しています。asp.net 4.5のWebサイトは何ですか。グローバルエラーキャッチャー。エラーが発生したオブジェクト名をキャッチしますか?
MonsterMMORPG 2013年

@MonsterMMORPGいいえ。上記の3つだけ
マークグラベル

1
@MarcGravellでは、ランタイム環境も4.5である必要がありますか、それともコンパイラの機能ですか?
kuldeep

5
C#は非常によく設計されています。私を驚かせ続けることは決してありません。マルク、ありがとう!
nmit026 2017年

74

StackFrame.GetFileLineNumberメソッドを使用します。次に例を示します。

private static void ReportError(string message)
{
     StackFrame callStack = new StackFrame(1, true);
     MessageBox.Show("Error: " + message + ", File: " + callStack.GetFileName() 
          + ", Line: " + callStack.GetFileLineNumber());
}

詳細については、Scott Hanselmanのブログエントリを参照してください。

[編集:以下を追加]

.Net 4.5以降を使用している場合は、System.Runtime.CompilerServices名前空間のCallerFilePathCallerMethodName、およびCallerLineNumber属性を検討してください。例えば:

public void TraceMessage(string message,
        [CallerMemberName] string callingMethod = "",
        [CallerFilePath] string callingFilePath = "",
        [CallerLineNumber] int callingFileLineNumber = 0)
{
    // Write out message
}

引数がなければなりませんstringためCallerMemberNameCallerFilePathしてintのためにCallerLineNumber、デフォルト値を持っている必要があります。メソッドパラメータにこれらの属性を指定すると、コンパイル時に呼び出しコードに適切な値を挿入するようにコンパイラに指示します。つまり、難読化によって機能します。詳細については、発信者情報を参照してください。


@MonsterMMORPGこれは、エラーの有無に関係なく機能します。StackFrameクラスは、現在実行中のメソッドを呼び出すメソッドを見ているだけです。StackFrameコンストラクターの最初の引数は呼び出し深度(1)で、2番目の引数はファイル情報が必要であることを示します。
akton 2012

3
あなたがコンパイルしている場合StackFrameに例のモノを、確認することで使用--debugコンパイル時と実行時に
ベルナールパウルス

StackFrame.NET Coreでは使用できません。マークグラベルの答えを使用してください。
ジェシーチザム2017年

デフォルト値を使用すると、「callingFilePathのデフォルトパラメータ値はコンパイル時の定数でなければならない」という= string.Emptyエラーがスローされます。
ストーマ

1
@stomyの""代わりに二重引用符()を使用するように試験を変更しましたstring.Empty
アクトン

21

私は1つのライナーを好むので:

int lineNumber = (new System.Diagnostics.StackFrame(0, true)).GetFileLineNumber();

8
これには.pdbファイル..が必要です。これは通常、生成サーバーに生成/コピーされません。
Deepak Sharma

4

.NET 4.0+メソッドソリューションが必要な場合:

using System;
using System.IO;
using System.Diagnostics;

public static void Log(string message) {
   StackFrame stackFrame = new System.Diagnostics.StackTrace(1).GetFrame(1);
   string fileName = stackFrame.GetFileName();
   string methodName = stackFrame.GetMethod().ToString();
   int lineNumber = stackFrame.GetFileLineNumber();

   Console.WriteLine("{0}({1}:{2})\n{3}", methodName, Path.GetFileName(fileName), lineNumber, message);
}

呼び出す方法:

void Test() {
   Log("Look here!");
}

出力:

Void Test()(FILENAME.cs:104)

ここを見て!

Console.WriteLine形式を好きなように変更してください!


3
すべての場合で機能するわけではありません。..pdbファイルが常に必要です。これは通常、生成サーバーに生成/コピーされません。C#5.0のCaller *属性で試してください。
Deepak Sharma、2015年

2
代わりにこれを使用する場合System.Diagnostics.Debug.WriteLine(String.Format("{0}({1}): {2}: {3}", fileName, lineNumber, methodName, message));、出力ウィンドウの行をクリックして、ソースのその行に移動できます。
Jesse Chisholm

3

try catchブロックにある場合は、これを使用してください。

try
{
    //Do something
}
catch (Exception ex)
{
    System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace(ex, true);
    Console.WriteLine("Line: " + trace.GetFrame(0).GetFileLineNumber());
}

1

.NET 4.5では、関数を作成して行番号を取得できます。

static int LineNumber([System.Runtime.CompilerServices.CallerLineNumber] int lineNumber = 0)
{
    return lineNumber; 
}

その後、呼び出すLineNumber()たびに、現在の回線が表示されます。これには、StackTraceを使用するどのソリューションよりも、デバッグとリリースの両方で機能するという利点があります。

したがって、必要なものの元の要求を受け取ると、次のようになります。

MessageBox.Show("Error enter code here line number " + LineNumber());

これは、Marc Gravellによる優れた回答に基づいています。


これは正しい行番号を返しません。なんらかの理由で191を差し引く必要があります。
ダニエル

面白い。ここでは問題なく動作します。IDEでリンク番号がオンになっていますか?この関数をファイルの別の場所から呼び出す場合でも、191を引く必要がありますか?これは、コンパイラのバグ(可能性は低いですが、可能性があります)またはページの折りたたまれたブロックのいずれかです(行番号が正しくなるのを妨げないはずですが、行番号を調べるのではなく、カウントしている場合の違いを説明している可能性があります)。オフラインでご連絡いただける場合は、最後までお問い合わせください。
Brian Cryer 2017

折りたたまれたブロックはなく、行番号はオンになっていますが、呼び出し元に関係なく、191を減算する必要があります。私は知っている...奇妙な。
ダニエル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.