问题描述
我已经编写了一个模块化的沙箱,旨在作为各种各样的生活组合使用,到目前为止,它的运行情况很好,但是我有一个想法,似乎无法弄清楚该怎么做。作为快速概述,当我有一个新想法或想要测试一个新概念时,我为它编写一个模块。每个模块都从SandBoxModule
派生而来,该模块包含一个称为Execute
的抽象方法。当我创建一个模块时,它看起来像这样:
public class DemoModule : SandBoxModule {
protected override void Execute() {
// Do something super cool and new.
}
}
没有什么可以阻止我创建其他方法来从Execute
方法中调用的,就像在其他任何自定义对象中一样:
public class DemoModule : SandBoxModule {
protected override void Execute() {
int x = 3;
SomethingSuperCoolAndNew(x);
}
private void SomethingSuperCoolAndNew(int someArg) {
// Do something super cool and new.
}
}
我如何以动态方式(例如,使用反射)捕获Execute
方法的代码内容以及它可能调用的任何方法,它们可能调用的任何方法,等等string
?
注意:如果有必要,我不反对使用第三方库。尽管如果没有它们也可以做到,但就沙盒的性质而言,我更愿意采用这种方式。
我已经研究过使用MethodBas.GetMethodBody()
,它不会返回我想要显示的内容。
一个可行的想法是从我的GitHub存储库加载源文件。在此期间,我会尝试一下,但我仍然想知道是否有一种方法可以避免跳过那一圈?
解决方法
Reflection使您可以发现类成员,例如属性或方法,但仅提供有关其签名的信息(参数名称和类型以及返回类型等),而没有有关其实现的信息。
如果您有权访问源代码,则可以使用C#编译器为您进行语法分析。
请参阅:Get started with syntax analysis (The .NET Compiler Platform SDK)。
特别是Traversing trees一章说明了如何发现代码的结构。
但是记录代码的更好方法是使用XML注释(也称为Documentation comments)。
在Build
页的项目选项中,选中XML documentation file
复选框,然后编写如下注释:
/// <summary>
/// Base module for sandboxed operations.
/// </summary>
public abstract class SandboxModule
{
/// <summary>
/// Implementing modues must override this method.
/// </summary>
protected abstract void Execute();
}
/// <summary>
/// This is my super cool demo module.
/// </summary>
public class DemoModule : SandboxModule
{
/// <summary>
/// Does something super cool and new.
/// </summary>
/// <remarks>It does so by calling the private method <c>SomethingSuperCoolAndNew</c>.</remarks>
protected override void Execute()
{
int x = 3;
SomethingSuperCoolAndNew(x);
}
/// <summary>
/// Important things happen here.
/// </summary>
/// <param name="someArg">Magic parameter.</param>
private void SomethingSuperCoolAndNew(int someArg)
{
// Do something super cool and new.
}
}
在输出目录(bin \ Debug)中,编译器将创建一个如下所示的XML文件:
<?xml version="1.0"?>
<doc>
<assembly>
<name>StackOverflowTests3</name>
</assembly>
<members>
<member name="T:StackOverflowTests3.SandboxModule">
<summary>
Base module for sandboxed operations.
</summary>
</member>
<member name="M:StackOverflowTests3.SandboxModule.Execute">
<summary>
Implementing modues must override this method.
</summary>
</member>
<member name="T:StackOverflowTests3.DemoModule">
<summary>
This is my super cool demo module.
</summary>
</member>
<member name="M:StackOverflowTests3.DemoModule.Execute">
<summary>
Does something super cool and new.
</summary>
<remarks>It does so by calling the private method <c>SomethingSuperCoolAndNew</c>.</remarks>
</member>
<member name="M:StackOverflowTests3.DemoModule.SomethingSuperCoolAndNew(System.Int32)">
<summary>
Important things happen here.
</summary>
<param name="someArg">Magic parameter.</param>
</member>
</members>
</doc>
此《 Visual Studio杂志》文章介绍了如何将这些XML文件转换为帮助文件:Doing Visual Studio and .NET Code Documentation Right。
甚至在Visual Studio的IntelliSense工具提示中也可以看到文档注释。