7

私の log4net ソリューションには、CallerInfo 属性を使用する API ラッパーがあります。

    public void Write(string message,
                            [CallerMemberName] string memberName = "",
                            [CallerFilePath] string filePath = "",
                            [CallerLineNumber] int lineNumber = 0)

ただし、Invoke メソッドで以下のように ICallHandler を使用するなど、前後の応答のトレース ロギングを実行できるように、Unity Interception も使用しています。

public class TraceCallHandler : ICallHandler
{
...

   public IMethodReturn Invoke(IMethodInvocation input, 
                               GetNextHandlerDelegate getNext)
    {
        //---- Trace method inputs
        this.LogInfoBeforeInvoke(input);

        //---- invoking the target method
        InvokeHandlerDelegate next = getNext();
        IMethodReturn methodReturn = next(input, getNext);

        //---- invoking the target method
        this.LogInfoAfterInvoke(methodReturn.ReturnValue); 
    }
}

注: 上記のコードは決して完全ではなく、正しくもありません... しかし、私が Unity Interception のために何をしていたかをお見せしたかっただけです。

私の質問/課題は次のとおりです。最終的に log.Write(...) を呼び出すとき、TraceCallHandler 情報ではなく、ターゲットの発信者情報が必要です。

たとえば、メソッド名については、次のようにできます。

   string methodName = input.MethodBase.Name;

発信者のファイル パスと発信者の行番号を取得するにはどうすればよいですか? リフレクションを介して行うことさえ可能ですか?

ありがとう!

4

2 に答える 2

8

はい、リフレクションを使用してこれらを取得できます。

var sf = new System.Diagnostics.StackTrace(1).GetFrame(0);
Console.WriteLine(" File: {0}", sf.GetFileName());
Console.WriteLine(" Line Number: {0}", sf.GetFileLineNumber());
// Note that the column number defaults to zero 
// when not initialized.
Console.WriteLine(" Column Number: {0}", sf.GetFileColumnNumber());

ただし、ドキュメントで明確に述べられているように:

StackFrame 情報は、デバッグ ビルド構成で最も有益です。デフォルトでは、デバッグ ビルドにはデバッグ シンボルが含まれますが、リリース ビルドには含まれません。デバッグ シンボルには、StackFrame オブジェクトの構築に使用されるファイル、メソッド名、行番号、および列情報のほとんどが含まれています。

したがって、これが必要なのはデバッグだけである場合は、デバッグ ビルドで有効にしてログを記録してください。リリース ビルドでは、上記のシンボルの考慮事項とは別に、コンパイラは積極的にメソッドをインライン化し、物事を並べ替え、一般的にあなたのものを台無しにするため、せいぜい役に立たず、最悪の場合はまったく誤解を招くでしょう。

于 2014-10-23T22:55:22.867 に答える