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);
}
}
7条答案
按热度按时间6xfqseft1#
我不知道它对你是否有用,但是VisualStudioAddins包含一个EnvDTE对象,它让你可以完全访问VB和C#语言解析器。
几年前我就稍微提到过它,我不知道它有多难用,也不知道它有多有效,但它确实看起来会给你你所需要的。
如果你阅读全文,它会告诉你如何从一个文件中提取函数的全文
希望这有帮助:)
euoag5mw2#
假设文件是有效的(即编译),您可以从将整个文件读入字符串开始。
我从你的问题中推断出你只对方法名感兴趣,而对类名不感兴趣,那么你需要一个正则表达式来给出 public的所有示例|受保护的|private,可选关键字virtual/override etc,MethodName,(,可选参数,)。如果有编码约定,这将有所帮助,因此您可以假设所有方法定义始终在一行中,而不是分散在几行中。
一旦你有了这些,就只需要计算{和}来得到函数体了。
最后一个建议:小心假设。他们有咬你屁股的坏习惯。
**EDIT:**哎哟,忘了注解了!如果你在方法体的注解中有括号,你的计数可能会出错。所以你需要从源代码中去掉所有注解作为你的第一步。
7gyucuyw3#
一般来说,你要解决的问题是以编译器的方式解析C#代码,然后保存函数的内容,而不是生成代码。因此,作为你解决方案的背景,你应该看看c#语法以及如何解析它们。
根据StingyJack的说法,一个简单的方法是创建一个只识别函数定义的正则表达式。然后你可以假设中间的所有东西都是函数体。然而,这种假设不会处理一个文件中的多个类,甚至是类末尾的尾随}。要处理这样的事情,你必须设计一个c#编译器。因为处理完整的C#语法是将正确地标识C#认为什么是函数的唯一事情。
b1payxdu4#
找到函数头之后,计算大括号的个数,直到找到函数的结尾。
idfiyjo85#
定制的解析器将是最好的选择。正如Blair在给StingyJack的评论中所说,用regex解析代码非常困难。我曾经尝试过一次,尽管可以用NET匹配平衡括号,但转义注解和字符串要复杂得多。
解析器应该会使事情变得简单得多。参见antlr获得一个好的生成器。
至于反射,我相信你可以尝试编译代码(只要你有所有必要的依赖项),然后像反射器一样访问它的内容。
66bbxpm56#
NRefactory是完成此任务的工具。请看这里:http://laputa.sharpdevelop.net/content/binary/NRefactory.wmv
pxy2qtax7#
您可以使用Microsoft.CodeAnalysis.CSharp执行此操作
下面的例子应该能让你了解,它假设你在一个命名空间里有一个类: