【问题标题】:Is there any way to get the list of functions from .cs file?有没有办法从 .cs 文件中获取函数列表?
【发布时间】:2012-08-26 06:45:19
【问题描述】:

我的经理要求我获取项目中每个 .cs 文件中可用的函数列表。

但是 .cs 文件的数量很大。

人工看很难。

有没有办法通过编写脚本或代码在.cs文件中找到函数名?

【问题讨论】:

  • 如果你把这些类编译成一个单独的 .DLL 可以吗?然后我可以给你一个解决方案?
  • 按文件还是按类型?如果您编译代码,或使用下面 JTMon 的答案,您将获得每种类型的方法,这些方法可能与源文件 1:1 对应,也可能不对应。

标签: c# powershell powershell-2.0


【解决方案1】:

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

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 文件,然后实现解析器可以区分每个文件中的方法声明(可能还需要词法分析器来帮助)。两者都没有什么特别困难的,但它们确实需要一些工作,而且太复杂,无法在此处作为答案包含在内。至少这是最简单的答案,可以涵盖我能想到的所有类型的方法声明,除非有人能提出更简单的方法。

【讨论】:

    【解决方案2】:

    【讨论】:

    • 在上面的链接上得到了 404
    【解决方案3】:

    如前所述使用反射 - 这将只返回您创建的函数:

      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 "";
        }
      }
    

    使用上面的测试类型,我提供的代码会打印Test2,因为这是一个函数。希望这就是您想要的。

    编辑:显然,您可以使用 GetMethods() 中的重载,使用另一篇文章中提到的绑定标志过滤到公共。

    【讨论】:

      【解决方案4】:

      如果您无法将 csharp 文件编译为程序集,您将不得不编写一个解析器。编写与方法声明匹配的正则表达式相当容易(查看 C# 语言规范)。但是你会得到一些误报(在块 cmets 中声明的方法),你还必须考虑 getter 和 setter。

      如果您有一个或多个程序集,这很容易。你甚至可以使用 Powershell 中的 System.Reflection:[System.Reflection.Assembly]::ReflectionOnlyLoad(..)。或者您可以使用 Mono.Cecil 进行组装检查。

      但如果您已经拥有这些程序集,请使用NDepend。您将获得比您需要的更多的代码信息,而且他们提供免费试用。

      【讨论】:

        【解决方案5】:

        如果其他人已经完成了艰苦的工作,请不要自己创造。

        既然您有源代码,请使用Sandcastle 之类的工具,该工具专为生成源代码文档而设计。您还没有指定输出需要的格式,所以这可能会也可能不会接受。

        这是您的项目/团队应该随时可以做的事情;有人可以在您完成 5 分钟后添加新方法或类,从而使您的工作过时。

        【讨论】:

          【解决方案6】:

          我已尝试使用以下代码,请尝试此代码。

          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();
              }
            }
          }
          

          【讨论】:

            【解决方案7】:

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2020-09-29
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2022-01-14
              • 2020-02-29
              • 1970-01-01
              • 2010-10-18
              相关资源
              最近更新 更多