3

我试图在调用该方法的解决方案中找到所有位置IBus.Publish<T>(来自 NServiceBus)。到目前为止,这是有效的:

IMethodSymbol method = ... [IBus.Publish methodsymbol resolved];
var callers = method.FindCallers(solution, new CancellationToken());

这导致 aIEnumerable<SymbolCallerInfo>并且我得到了对该方法的所有正确引用。

我现在将如何获得IBus.Publish调用通用参数的方法?我是否必须手动解析源树,或者它是否存在一些我可以利用的 Roslyn 魔法?

例子:

在我的代码中,我有:

IBus _bus;

_bus.Publish<IMyMessage>(msg => { msg.Text = "Hello world"});

我有兴趣获得IMyMessage类型。

非常感谢帮助!

4

2 回答 2

5

您可以使用 aSemanticModelSyntaxNodefor 调用转到实际的MethodSymbol,然后您只需读取TypeArguments属性即可获取TypeSymbol参数的 s 。如果没有明确指定参数,这甚至会起作用,因为SemanticModel它将执行类型推断。

例如:

var callers = method.FindCallers(solution, CancellationToken.None);
foreach (var caller in callers)
{
    foreach (var location in caller.Locations)
    {
        if (location.IsInSource)
        {
            var callerSemanticModel = solution
                .GetDocument(location.SourceTree)
                .GetSemanticModel();
            var node = location.SourceTree.GetRoot()
                .FindToken(location.SourceSpan.Start)
                .Parent;
            var symbolInfo = callerSemanticModel.GetSymbolInfo(node);
            var calledMethod = symbolInfo.Symbol as IMethodSymbol;
            if (calledMethod != null)
            {
                var arguments = calledMethod.TypeArguments;
            }
        }
    }
}
于 2013-10-17T13:50:45.283 回答
1

我不太熟悉 IMethodSymbol 和 ISymbol 接口,但这是另一种从InvocationExpressionSyntax

var methodRef = (InvocationExpressionSyntax)find_method();

var genericArguments = methodRef.DescendantNodes().OfType<GenericNameSyntax>().FirstOrDefault();

if (genericArguments != null)
   foreach (var g_arg in genericArguments.TypeArgumentList.Arguments)
      Console.WriteLine(g_arg);

static InvocationExpressionSyntax find_method()
{
   var code = new StreamReader("..\\..\\Tests.cs").ReadToEnd();
   SyntaxTree tree = SyntaxTree.ParseText(code);
   var root = tree.GetRoot();
   //find your methods here
   return (InvocationExpressionSyntax)root.DescendantNodes().ToArray()[88];
}
于 2013-10-16T08:26:06.553 回答