Как создать предсказуемый вывод с помощью Lazy <StackFrame> - PullRequest
3 голосов
/ 20 декабря 2010

Я работаю над некоторой внутренней структурой ведения журналов, и ради производительности кажется хорошей идеей лениво получить 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, пока я не обнаружу первый кадр неизвестным методом.

Я действительно надеюсь, что есть лучшее решение.

1 Ответ

0 голосов
/ 22 декабря 2010

Я не знаю, что это намного лучше, но вместо того, чтобы искать неизвестный метод, было бы проще искать другой исходный класс.Это немного грубо, но что-то вроде этой работы даст вам последний кадр перед входом в класс ведения журнала без необходимости вести список «известных» имен методов (при условии, что метод ведения журнала не является статическим ...)?

public void DoStuff()
{
    int index = 0;
    StackFrame frame = new StackFrame(index++);
    while (this.GetType().Name.Equals(frame.GetMethod().DeclaringType.Name))
    {
        frame = new StackFrame(index++);
    }
    //...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...