从CS文件中获取方法的内容

5
我有一个需求,需要将cs文件中每个方法的内容都存储成字符串。我想要的是输入一个cs文件后,返回一个字典,其中方法名作为键,方法体作为值。
我已经尝试过正则表达式和反射,但是没有成功,有人能帮忙吗?
谢谢。
7个回答

6
我不知道这是否对您有用,但Visual Studio Addins包括EnvDTE对象,该对象可让您完全访问VB和C#语言解析器。 请参见使用代码模型发现代码
我曾经在多年前略微涉及过它,我不知道它的使用难度或有效性如何,但它似乎会给您提供所需内容。
代码模型允许自动化客户端避免为了发现项目中的高级定义(例如类、接口、结构、方法、属性等)而实现Visual Studio语言的解析器。
如果您阅读完整篇文章,它将告诉您如何从文件中提取函数的完整文本。
希望这能帮到您 :)

2
假设文件有效(即编译通过),您可以先将整个文件读入字符串中。
我从您的问题中了解到,您只对方法名感兴趣,而不是类名。然后您需要用正则表达式获得所有实例:public | protected | private,可选关键字virtual / override等,MethodName,(可选参数),)。
如果有编码约定,假设所有方法定义始终在一行中,而不是分布在几行中,则会有所帮助。
一旦您获取到这些内容,只需要计算{ 和 } 的数量就能得到函数体。
最后一个建议:小心假设。他们有咬人的厉害习惯。
编辑:哎呀,忘记注释了!如果方法体中的注释中有括号,您的计数可能会出错。因此,您需要在第一步中剥离源代码中的所有注释。

1
一般来说,你尝试解决的问题是以编译器相同的方式解析C#代码,然后保存函数内容而不是生成代码。因此,在解决方案背景中,您应该查看C#语法和如何解析它们。
根据StingyJack的建议,一个简单的方法是创建一个仅识别函数定义的正则表达式。然后,您可以假设之间的所有内容都是函数体。但是,这种假设不会处理在一个文件中有多个类或甚至是类末尾的 } 符号。为了处理这样的情况,您必须设计一个C#编译器,因为处理完整的C#语法是唯一能正确地识别C#认为是函数的内容。

0

你可以使用Microsoft.CodeAnalysis.CSharp来实现这个功能。

下面的示例应该能够帮助你。它假设你在一个命名空间中有一个类:

var output = new Dictionary<string, string>();

var csFilePath = @"C:\File.cs";
var csFileContent = File.ReadAllText(csFilePath);
SyntaxTree tree = CSharpSyntaxTree.ParseText(csFileContent );
CompilationUnitSyntax root = tree.GetCompilationUnitRoot();
var nds = (NamespaceDeclarationSyntax)root.Members[0];
var cds = (ClassDeclarationSyntax) nds.Members[0];

foreach(var ds in cds.Members){
    //Only take methods into consideration
    if(ds is MethodDeclarationSyntax){
        var mds = (MethodDeclarationSyntax) ds;
        
        //Method name
        var methodName = ((SyntaxToken) mds.Identifier).ValueText;
        
        //Method body (including curly braces)
        var methodBody = mds.Body.ToString();
        
        output.Add(methodName, methodBody);
    }
}

0
在找到函数头之后,数一下大括号的数量,直到找到函数的结尾。

只要注释或字符串中没有不平衡的 {},就可以了... 并且依赖于能够识别方法的开头。 - Blair Conrad

0
一个定制的解析器将是最佳选择。正如Blair在对StingyJack的评论中所述,使用正则表达式解析代码非常困难。我曾经尝试过,虽然使用.NET可以匹配平衡的大括号,但转义注释和字符串则要复杂得多。
解析器应该会让事情变得简单得多。请参见antlr以获取一个好的生成器。
至于反射,我相信你可以尝试编译代码(只要你有所有必要的依赖项),然后像Reflector一样访问其内容。但我还是会选择解析器。

0

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