直接找到&间接方法用于在基类中覆盖方法

时间:2016-06-09 13:24:37

标签: ndepend

请帮我弄清楚如何编写查询:)

代码是:

namespace ConsoleApplication1
{
    class Program
    {
        static void Main()
        {
            var man = new Man("Joe");

            Console.WriteLine(man.ToString());
        }
    }

    public class SuperMan
    {
        public SuperMan(string name)
        {
            this.name = name;
        }

        public override string ToString()
        {
            return name;
        }

        string name;
    }

    public class Man : SuperMan
    {
        public Man(string name) : base(name)
        {
        }
    }
}

我想找到Man.ToString()的所有直接和间接依赖(方法)。 Main()方法只有一个调用。

我尝试的查询是:

from m in Methods 
let depth0 = m.DepthOfIsUsing("ConsoleApplication1.SuperMan.ToString()")
where depth0  >= 0 orderby depth0
select new { m, depth0 }.

但它没有找到依赖的Program.Main()方法......

如何修改查询以便找到这种方法的用法?

1 个答案:

答案 0 :(得分:0)

首先让我们看看直接来电者。我们希望列出调用SuperMan.ToString()的所有方法或ToString()覆盖的任何SuperMan.ToString()方法。它看起来像:

let baseMethods = Application.Methods.WithFullName("ConsoleApplication1.SuperMan.ToString()").Single().OverriddensBase
from m in Application.Methods.UsingAny(baseMethods)
where m.IsUsing("ConsoleApplication1.Man")  // This filter can be added
select new { m, m.NbLinesOfCode }

注意我们放了一个filter子句,因为在现实世界中,几乎每个方法都调用object.ToString()(这是一个特例)。

现在要处理间接调用,这更棘手。我们需要在泛型序列上调用神奇的FillIterative()扩展方法。

let baseMethods = Application.Methods.WithFullName("ConsoleApplication1.SuperMan.ToString()").Single().OverriddensBase
let recursiveCallers = baseMethods.FillIterative(methods => methods.SelectMany(m => m.MethodsCallingMe))

from pair in recursiveCallers 
let method = pair.CodeElement
let depth = pair.Value
where method.IsUsing("ConsoleApplication1.Man") // Still same filter
select new { method , depth }

Etvoilà!

NDepend Code Query Direct Indirect Method Call