假设我们有以下基本模型:
public class Base
{
...
}
并且有M 1 , ..., M n模型派生自这个模型。
我们有一个具有以下结构的接口:
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 可以是M 1 , ..., M n 中的任何类型。
我设法从语法树、它的实现和参数类型中找到了接口,甚至找到了调用者,但我在IExampleInterface.DoSomething调用中找不到传递参数的类型。
这是代码:
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调用的参数类型?
我实际上通过获取编译的语义模型解决了这个问题。
首先,在找到所有调用者之后,我们需要借助来自SymbolCallerInfo的CallingSymbol来找到InvocationExpression节点。
其次,我们必须从InvocationExpression 的ArgumentList属性中获取我们感兴趣的参数。
假设arg是所需的参数,而compiler是arg来自的 Compilation 实例。
var type = compilation
.GetSemanticModel(arg.SyntaxTree)
.GetTypeInfo(arg.ChildNodes().First());
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句