是否可以实例化并调用我的Analyzer正在分析的类的方法?

时间:2016-02-17 00:15:29

标签: c# roslyn analyzer roslyn-code-analysis

我的分析器将匹配具有特定签名的方法。我想从我的分析器内部创建一个类I的实例,分析并调用导致分析器启动的方法。

假设源代码处于可编译状态,是否可能?

获取类名和方法名非常简单,但Type.GetType(...)将始终返回null。

这样做的目的是,当我使用测试方法并运行它时,我希望我的分析器启动,如果测试失败则失败。

如果代码还没有准备好进行编译,那么返回就可以了。

2 个答案:

答案 0 :(得分:1)

似乎可能,但您需要检查这些解决方案的效率。此外,您无法保证代码可编译。

您可以抓取Compilation对象(来自说context.SemanticModel.Compilation),在其上调用Emit,然后将其写入光盘。然后使用Assembly.Load加载它,然后使用它进行简单的反射来实例化您已经知道其名称的类,并使用适当的参数调用该方法。

另一种方法是在脚本会话中使用Compilation作为引用程序集,并使用Roslyn Scripting API来调用该方法。 ToMetadataReference上有一个Compilation方法,因此您可以获得MetadataReference,然后可以将其传递给ScriptOptions.Default.AddReferences。然后,您需要将生成的选项实例传递给CSharpScript.EvaluateAsync()

答案 1 :(得分:0)

还有另一个根本原因,你可以从用户的编译中运行代码,即使它确实编译了 - 它可能是错误的环境。考虑一下您在Windows上使用Windows Phone,Xamarin Android / iOS,.NET Core或其他任何方式的方案。在任何这些情况下,编译器都有可以编译引用程序集,但显然你无法实际运行该代码,因为它的目标是不同的平台。人们经常会问为什么你不能将ITypeSymbol转换为反射System.Type并返回,这也是原因之一 - 编译器可以在平台B的平台A上编译代码,当它可以'实际上,首先运行(或完全加载)B组件。