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

Is it possible to instantiate and call a method of the class my Analyzer is analyzing right now?

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

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

获取 class 名称和方法名称非常容易,但是 Type.GetType(...) 将始终 return null。

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

如果代码还没有准备好编译,直接return.

就好了

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

您可以获取 Compilation 对象(假设来自 context.SemanticModel.Compilation),对其调用 Emit,然后将其写入光盘。然后使用 Assembly.Load 加载它,然后它是简单的反射来实例化 class,其名称你已经知道,并使用适当的参数调用它的方法。

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

还有一个根本原因是您不能 运行 用户编译的代码,即使它确实编译了——它可能是错误的环境。考虑这样一种情况,您的目标是 Windows Phone 或 Xamarin Android/iOS、Linux 上的 .NET Core 或其他任何内容。在任何这些情况下,编译器都有参考程序集,您可以 against 但显然您实际上不能 运行 该代码,因为它针对不同的平台。人们经常问为什么不能将 ITypeSymbol 转换为反射 System.Type 并返回,这是原因之一——编译器可以在平台 A 上为平台 B 编译代码,而实际上它不能运行(或完全加载)B 的程序集放在首位。