3

私はいくつかの内部ロギング フレームワークに取り組んでおり、パフォーマンスのために、遅延してStackFrame. StackFrameこれを使用して、ロギング フレームワーク外の最初のメソッドを取得したいと考えています。

私の最初のアイデアはこれでした:

using System;
using System.Diagnostics;
using NUnit.Framework;

[TestFixture]
public class Test
{
    [Test]
    public void Caller()
    {
        NeedsToNowCaller();
    }

    public void NeedsToNowCaller()
    {
        Processor.GetName(() => new StackFrame(4));

        Really();
        Assert.AreEqual("Caller", Processor.stackFrame.Value.GetMethod().Name);
    }

    public void Really()
    {
        Assert.AreEqual("Caller",Processor.stackFrame.Value.GetMethod().Name);
    }
}

public static class Processor
{
    public static Lazy<StackFrame> stackFrame;

    public static void GetName(Func<StackFrame> stackFrameProvider)
    {
        stackFrame = new Lazy<StackFrame>(stackFrameProvider);
    }
}

しかし、これらの行を交換すると:

    Really();
    Assert.AreEqual("Caller", Processor.stackFrame.Value.GetMethod().Name);

コール スタックが変更されるため、結果は予測できません。怠惰を維持しながら、クロージャーを介してローカルスコープ/フレームへのフックを取得する方法はありますか。

私が考えることができる唯一の解決策は、不明な方法で最初のフレームを検出するまで、StackTrace をステップ実行することです。

より良い解決策があることを本当に願っています。

4

1 に答える 1

0

これがはるかに優れているかどうかはわかりませんが、未知のメソッドを探す代わりに、別のソース クラスを探すほうが簡単かもしれません。これは少し大雑把ですが、「既知の」メソッド名のリストを維持する必要なく、ロギング クラスに入る前に最後のフレームを取得するために、このように機能しますか (ロギング メソッドが静的でないと仮定します...)?

public void DoStuff()
{
    int index = 0;
    StackFrame frame = new StackFrame(index++);
    while (this.GetType().Name.Equals(frame.GetMethod().DeclaringType.Name))
    {
        frame = new StackFrame(index++);
    }
    //...
}
于 2010-12-22T15:12:58.813 に答える