powershell 有没有办法从.cs文件中获取函数列表?

qlfbtfca  于 2023-02-19  发布在  Shell
关注(0)|答案(8)|浏览(135)

我的经理让我获取项目中每个.cs文件内可用函数的列表。
但是.cs文件的数量是巨大的。
很坚韧通过手动方式查看。
有没有办法通过编写脚本或代码来查找.cs文件中的函数名?

mzaanser

mzaanser1#

使用反射。如果所有文件都在项目中,则可以使用:

Type[] types = Assembly.GetExecutingAssembly().GetTypes();
foreach (Type toCheck in toProcess)
{
    MemberInfo[] memberInfos = toCheck.GetMembers(BindingFlags.NonPublic | BindingFlags.Public | OtherBindingFlagsYouMayNeed);
    //Loop over the membersInfos and do what you need to such as retrieving their names
    // and adding them to a file
}

如果项目编译为dll,则可以使用:

Assembly assembly = Assembly.LoadFrom(filePath); //filePath is for the dll
Type[] toProcess = assembly.GetTypes();
//rest of the code is same as above

编辑:如果您想找出@BAF提到的每个物理文件的函数,您将获得程序集的基目录(通过. CodeBase),然后执行目录树遍历,查找所有. cs文件,然后实现可以区分方法声明的解析器(可能还需要一个词法分析器来帮助)。这两个问题都没有什么特别困难的,但它们确实需要一些工作,而且太复杂了,不能在这里作为答案。至少这是最简单的答案,它涵盖了我能想到的所有类型的方法声明,除非有人能建议一种更简单的方法。

rdlzhqv9

rdlzhqv93#

使用前面提到的反射--这将只返回您所创建的函数:

Assembly a = Assembly.LoadFile("Insert File Path");
  var typesWithMethods = a.GetTypes().Select(x => x.GetMethods(BindingFlags.Public).Where(y => y.ReturnType.Name != "Void" &&
                                                    y.Name != "ToString" &&
                                                    y.Name != "Equals" &&
                                                    y.Name != "GetHashCode" &&
                                                    y.Name != "GetType"));
  foreach (var assemblyType in typesWithMethods)
  {
    foreach (var function in assemblyType)
    {
      //do stuff with method
    }
  }

您将有一个类型列表,然后在每个类型中有一个函数列表。

public class TestType
  {
    public void Test()
    {

    }
    public string Test2()
    {
      return "";
    }
  }

使用上面的测试类型,我提供的代码将打印Test 2,因为这是一个函数。希望这是你正在寻找的。
编辑:显然,您可以使用GetMethods()中的重载,使用另一篇文章中提到的绑定标志过滤到public。

ulydmbyx

ulydmbyx4#

如果你不能把csharp文件编译成汇编文件,你必须写一个解析器。写一个正则表达式来匹配一个方法声明是相当容易的(看看C#语言规范)。但是你会得到一些误报(方法声明在块注解中),你也必须考虑getter和setter。
如果你有一个或多个程序集,这是相当容易的。你甚至可以使用powershell的System.Reflection:[System.Reflection.Assembly]::ReflectionOnlyLoad(..) .也可以使用Mono.塞西尔进行装配检查。
但是如果你已经有了程序集,那么就使用NDepend,你会得到比你需要的更多的代码信息,而且他们有免费试用版。

k4aesqcs

k4aesqcs5#

如果别人已经做了艰苦的工作,就不要自己创造。
既然你有源代码,就用Sandcastle这样的工具来生成源代码文档,你还没有指定输出的格式,所以这可能是可以接受的,也可能是不可以接受的。
这是您的项目/团队应该能够在任何时候做的事情;有人可能在您完成后5分钟添加新的方法或类,从而使您的工作过时。

mf98qq94

mf98qq946#

我已经尝试了以下代码,请尝试这一个。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace filedetection
{
class Program
{
    static void Main(string[] args)
    {
        string path = @"D:\projects\projectsfortest\BusinessTest";
        DirectoryInfo d = new DirectoryInfo(path);//Assuming Test is your Folder
        FileInfo[] Files = d.GetFiles("*.cs"); //Getting Text files
        string str = "";
        foreach (FileInfo file in Files)
        {                
            Program program = new Program();
            List<string> allmethord = program.GetAllMethodNames(path+"\\"+file.Name);
            foreach (string methord in allmethord)
            {
                Console.WriteLine(methord);
            }
        }

        Console.ReadKey();
    }

    public List<string> GetAllMethodNames(string strFileName)
    {
        List<string> methodNames = new List<string>();
        var strMethodLines = File.ReadAllLines(strFileName)
                                    .Where(a => (a.Contains("protected") ||
                                                a.Contains("private") ||
                                                a.Contains("public")) &&
                                                !a.Contains("_") && !a.Contains("class"));
        foreach (var item in strMethodLines)
        {
            if (item.IndexOf("(") != -1)
            {
                string strTemp = String.Join("", item.Substring(0, item.IndexOf(")")+1).Reverse());
                strTemp = String.Join("", strTemp.Substring(0, strTemp.IndexOf("  ")).Reverse());
                methodNames.Add(strTemp);                    
            }
        }
        return methodNames.Distinct().ToList();
    }
  }
}
pdkcd3nj

pdkcd3nj7#

在“项目属性”的“生成”部分中,启用XML文档文件。生成项目。输出XML文件将提供所有类及其方法、参数名称/类型等的列表。

knsnq2tg

knsnq2tg8#

您可以使用Microsoft.CodeAnalysis.CSharp执行此操作
下面的例子应该能让你了解,它假设你在一个命名空间里有一个类:

var output = new List<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;
        
        output.Add(methodName);
    }
}

相关问题