【问题标题】:C# code listing all methods called from a starting method?C# 代码列出从起始方法调用的所有方法?
【发布时间】:2013-11-11 06:45:54
【问题描述】:

假设我们有调用methodB()和methodC()的methodA()。

在methodB()中,我们调用methodB1()和methodB2()。

在methodC()中,我们调用methodC1()、methodC2()和methodC3()。

所以最后我们有了方法树

方法A

方法B

方法B1

方法B2

方法C

方法C1

方法C2

方法C3

是否可以通过 C# 代码获得此列表?

【问题讨论】:

标签: c# methods


【解决方案1】:

当我们考虑确定调用流程时,首先想到的是检查调用堆栈。但是检查堆栈帧只能给我们当前的调用层次结构,而不是之前的调用层次结构。即即使您在 C3 中检查堆栈帧,它也不会有 A 调用 B 的历史记录。所以这不起作用。

这意味着每个被调用的方法也需要以某种方式参与实现这个目标。每个方法都必须以某种方式确定调用者想要跟踪流,并且必须为提供所需信息做出贡献。但是在每个可能调用的方法中添加一些代码实在是太荒谬了。

这样做的另一种方法是将其委托给可以拦截每个方法调用的人,检查调用者是否想要跟踪流程并记录以后可以访问的所需信息。这正是我认为 面向方面编程 (AOP) 出现的地方。要在 .Net 中使用 AOP,请查看 PostSharp。如果我有时间,我会尝试提供一些代码示例,但现在我只能指向这个网址:http://www.postsharp.net

我希望这会有所帮助。

【讨论】:

  • 谢谢。看起来对我很有帮助!
【解决方案2】:

如果您能够将每个特定操作作为一个单独的类来实现(我建议这样做),则如下所示。如果没有,您应该使用AOP。对于 AOP,我会推荐 Castle Dynamic Proxy

class Program
{
    static void Main(string[] args)
    {
        new A().Invoke();
        CallStack.Get().ToList().ForEach(Console.WriteLine);
        Console.ReadKey();
    }
}

public class CallStack
{
    private CallStack()
    {
        _callStack = new Stack<string>();
    }
    private static CallStack _singleton;
    private  Stack<string> _callStack;
    public static CallStack Get()
    {
        if (_singleton == null) _singleton = new CallStack();
        return _singleton;
    }
    public static void Push(string call)
    {
        Get()._callStack.Push(call);
    }
    public List<string> ToList()
    {
        return new List<string>(_callStack);
    }
}

public abstract class MethodBase
{
    protected void Trace()
    {
        CallStack.Push(GetType().Name);
    }
    protected abstract void Operation();
    public void Invoke()
    {
        Trace();
        Operation();
    }
}

public class A : MethodBase
{
    protected override void Operation()
    {
        new B().Invoke();
        new C().Invoke();
    }
}

public class B : MethodBase
{
    protected override void Operation()
    {
        new B1().Invoke();
        new B2().Invoke();
    }
}

public class C : MethodBase
{
    protected override void Operation()
    {
        new C1().Invoke();
        new C2().Invoke();
        new C3().Invoke();
    }
}

public class B1 : MethodBase
{
    protected override void Operation() { }
}

public class B2 : MethodBase
{
    protected override void Operation() { }
}

public class C1 : MethodBase
{
    protected override void Operation() { }
}

public class C2 : MethodBase
{
    protected override void Operation() { }
}

public class C3 : MethodBase
{
    protected override void Operation(){}
}

【讨论】:

  • 谢谢!看起来对我很有帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-08
  • 1970-01-01
  • 2013-01-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多