【发布时间】:2020-04-16 09:58:13
【问题描述】:
假设我们有以下基本模型:
public class Base
{
...
}
并有 M1, ..., Mn 个从这个模型派生的模型。
我们有一个结构如下的接口:
public interface IExampleInterface
{
void DoSomething(Base input);
}
假设我们对这个类有一个简单的实现,例如:
public class Example : IExampleInterface
{
void DoSomething(Base input)
{
System.Console.WriteLine("Please help me!!");
}
}
IExampleInterface.DoSomething 方法有很多调用,在整个解决方案中具有不同的输入参数。
var ex = new Example();
var m = new M();
ex.DoSometing(m);
其中 M 可以是 M1、...、Mn 中的任何类型。 p>
我设法从语法树中找到了接口,它的实现和参数类型,甚至更多我找到了调用者,但是我在 IExampleInterface.DoSomething em> 来电。
代码如下:
var interfaceName = "IExampleInterface";
var returnType = "Void";
var methodName = "DoSomething";
var arg = "Base";
var exInterface = compilations
.SelectMany(compilation => compilation.SyntaxTrees.Select(syntaxTree => compilation.GetSemanticModel(syntaxTree)))
.SelectMany(
semanticModel => semanticModel
.SyntaxTree
.GetRoot()
.DescendantNodes()
.OfType<InterfaceDeclarationSyntax>()
.Select(interfaceDeclarationSyntax => semanticModel.GetDeclaredSymbol(interfaceDeclarationSyntax)))
.Where(s => s.Name == interfaceName)
.FirstOrDefault();
var implementations = await SymbolFinder.FindImplementationsAsync(exInterface, solution);
var implementation = implementations.FirstOrDefault() as ITypeSymbol;
var method = exInterface
.GetMembers(methodName)
.Where(m => m.Kind == SymbolKind.Method)
.Cast<IMethodSymbol>()
.FirstOrDefault(m =>
m.Parameters != null &&
m.Parameters.Length == 1 &&
m.Parameters[0].Type.Name == arg &&
m.ReturnType.Name == returnType);
var callers = await SymbolFinder.FindCallersAsync(method, solution);
此时我被卡住了。我对 Roslyn 比较陌生。我的问题是如何找到传递给 IExampleInterface.DoSomething 调用的参数类型?
【问题讨论】:
-
我认为你将不得不获得SemanticModel,类似于 var model = compilation.GetSemanticModel(tree); 然后你可以使用类似模型的东西.GetSymbolInfo() 以获取有关该符号的信息。我不确定细节。
-
@PhilJollans 亲爱的菲尔,感谢您的建议。我实际上是借助语义模型解决了这个问题。
标签: c# metaprogramming roslyn static-analysis analyzer