我的经理要求我获取项目中每个 .cs 文件中可用的函数列表。
但是 .cs 文件的数量很大。
手动看很难。
有没有办法通过编写脚本或代码在 .cs 文件中找到函数名?
我的经理要求我获取项目中每个 .cs 文件中可用的函数列表。
但是 .cs 文件的数量很大。
手动看很难。
有没有办法通过编写脚本或代码在 .cs 文件中找到函数名?
使用反射。如果所有文件都在项目中,那么您可以使用:
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 文件,然后您将实现一个可以区分每个文件中的方法声明的解析器(可能还需要一个词法分析器来帮助解决这个问题)。两者都没有什么特别困难的,但它们确实需要一些工作,而且太复杂,无法在此处作为答案包含在内。至少这是最简单的答案,它将涵盖我能想到的所有类型的方法声明,除非有人能提出更简单的方法。
你看过罗斯林吗?
检查 Doug Finke 的 Get-RoslynInfo 脚本 cmdlet:http: //www.dougfinke.com/blog/index.php/2011/10/30/analyze-your-c-source-files-using-powershell-and-the -get-roslyninfo-cmdlet/
如果其他人已经完成了艰苦的工作,请不要自己创造东西。
由于您拥有源代码,因此请使用Sandcastle之类的工具,该工具旨在生成源代码文档。您还没有指定输出需要采用什么格式,因此这可能是可接受的,也可能是不可接受的。
这是您的项目/团队应该随时可以做的事情;有人可以在您完成 5 分钟后添加新方法或类,从而使您的工作过时。
如果您无法将 csharp 文件编译为程序集,则必须编写一个解析器。编写与方法声明匹配的正则表达式相当容易(查看 C# 语言规范)。但是你会得到一些误报(在块注释中声明的方法),你还必须考虑 getter 和 setter。
如果您有一个或多个程序集,这很容易。您甚至可以使用来自 powershell: 的 System.Reflection [System.Reflection.Assembly]::ReflectionOnlyLoad(..)
。或者您可以使用 Mono.Cecil 进行装配检查。
但是,如果您已经拥有程序集,请使用NDepend。您将获得比您需要的更多的代码信息,并且他们可以免费试用。
如上所述使用反射 - 这将仅返回您所做的功能:
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() 中的重载,使用另一篇文章中提到的绑定标志过滤到公共。
我已尝试使用以下代码,请尝试此代码。
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();
}
}
}