我正在尝试静态构建 C# 解决方案的调用层次结构,或者换句话说,尝试找出解决方案中的每个方法都进行了哪些方法调用。
我稍微修改了另一个问题的代码片段,但它并没有完全削减它:
每当调用基类方法并且该方法又调用在子类中实现的抽象或虚拟方法时,链就会中断。
var syntaxTree = SyntaxTree.ParseText(Code);
var compilation = Compilation.Create("name").AddSyntaxTrees(syntaxTree);
var semanticModel = compilation.GetSemanticModel(syntaxTree);
var methods = syntaxTree.GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>();
foreach (var method in methods)
{
var invocations = method.DescendantNodes().OfType<InvocationExpressionSyntax>();
foreach (var syntax in invocations)
Debug.WriteLine(semanticModel.GetDeclaredSymbol(method) + " calls method " +
semanticModel.GetSymbolInfo(syntax).Symbol);
}
这是一些示例代码来说明问题。基类方法 Bar 调用 C2 中实现的抽象方法 Baz。
class Program2
{
void Main()
{
new C2().Bar();
}
}
abstract class C1
{
public void Bar()
{
Baz();
}
public abstract void Baz();
}
class C2 : C1
{
public override void Baz() { }
}
但是,在示例代码上运行顶部代码片段时,它认为调用是对 C1.Baz():
Program2.Main() calls method C1.Bar()
C1.Bar() calls method C1.Baz()
我们如何使用语义模型来确定实际上是 C2.Baz() 将执行?