如何在Roslyn上使用扩展方法?

6

我需要列出文件中找到的所有扩展方法。

目前我的做法是(看起来正常):

var methods = nodes.OfType<MethodDeclarationSyntax>();    
var extensionMethods = methods.Where(m => 
        m.Modifiers.Any(t => t.Kind == SyntaxKind.StaticKeyword) 
        && m.ParameterList.Parameters.Any(p => 
            p.Modifiers.Any(pm => pm.Kind == SyntaxKind.ThisKeyword)));

虽然我没有测试所有情况,但看起来这个方法是有效的。不过我想知道是否有更简洁的解决方法。

是否有类似IsExtension或SyntaxKind.ExtensionMethod的东西?我查看了一下,但没有找到明显的答案。

我正在使用最新的Roslyn Sept/12版本。

1个回答

6

您正在进行语法级别的工作,在这个级别上,不存在“扩展方法”的概念。您可以做的是获取每个方法的语义信息(称为Symbol),在那里您将看到它是否是扩展方法。类似于以下内容:

SyntaxTree tree = …
var compilation = Compilation.Create("foo").AddSyntaxTrees(tree);
var model = compilation.GetSemanticModel(tree);

var methods = …
var extensionMethods =
   methods.Where(m => model.GetDeclaredSymbol(m).IsExtensionMethod);

这意味着您的代码实际上需要编译,您还需要添加任何必要的编译参考。

谢谢您的答复,它起作用了。我只是想知道是否可以使用我的方法来避免添加参考资料。我希望尽可能让项目独立。谢谢。 - eestein
是的,如果您不想添加引用,那么我认为您的方法是合理的。 - svick
由于扩展方法的语法已经定义得很好,因此最好使用基于语法的解决方案,而不是引入SemanticModel,因为即使现在SemanticModel比仅使用语法树要慢。 - Rikki Gibson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接