有没有办法找出所有在C#世界中作为程序一部分执行的函数调用?
例如,鉴于此:
static void Main(string[] args)
{
if (true)
{
CallTrueFunction();
}
else
{
CallFalseFunction();
}
}
我可以通过FxCop或其他系统来了解CallTrueFunction吗?
答案 0 :(得分:10)
简短的回答是否。
稍微长一点的答案是否定的,不适用于任何编程语言中的任何非平凡程序。
答案越长,您或多或少都会描述 the halting problem 。没有通用的方法来确定哪些方法可以访问,哪些不是因为这样做你需要解决暂停问题。
想象一个while
循环,循环之后是对myfunc()
的唯一调用。是myfunc()
吗?你无法知道,因为循环可能会或可能不会终止。也许循环依赖于传递给函数的变量。也许它依赖于用户的输入。无论如何,如果循环终止,则调用myfunc()
。如果循环没有终止,那么myfunc()
是永远不会被调用的死代码。我们只说你做while(Console.ReadLine() != "G") { }
。你的程序是否致电myfunc()
?取决于输入!
就像暂停问题一样,你可以构建一些简单的小程序,它们总能产生正确的答案,或者创建极其微小的有限状态机,它们总能产生正确的答案。但是,如果你接下来的静态分析程序并在一个中等规模的app上运行它,那么潜在状态组合的数量会迅速超过宇宙中可用原子的数量。
了解程序是否会调用此函数或该函数的唯一方法是运行它并查看是否存在。然后,您可以说“对于输入X,在环境Y中,在CPU Z上,在日期时间D,给定这些系统库的这些版本,同时系统处于此CPU负载量以及此I / O负载量,如果地面振动没有中断硬盘,并且宇宙射线没有翻转内存中的任何位,我的程序称为所有可用函数F“的子集G.”。
如果这些变量中的任何一个发生变化(输入是主要变量),那么之前的分析就不完整了。
注意:甚至不可能强烈保证可以调用哪些函数,因为反射可以通过构造字符串来调用任何函数(因此您甚至无法扫描函数名称),甚至生成和注入品牌新功能进入你的程序。
答案 1 :(得分:2)
根据您想要实现的目标,一种可能的方法是以相反的方式处理事物并标记/删除无法到达的所有内容。使用Resharper,您可以轻松找到all unused code。按照你的例子,这将标记:
else
{
CallFalseFunction();
}
作为无法访问的代码。它会建议你改变:
if (true)
{
CallTrueFunction();
}
为:
CallTrueFunction();
一旦你以这种方式清理你的项目,剩下的一切都应该通过一些执行路径调用,并且应该调用所有不依赖于条件参数的东西(假设程序没有中途中止)。
在尝试使用特定参数查找应用中特定入口点调用的方法时,这无助于您。如果这是您正在寻找的,也许您可以尝试使用能够记录所调用的每个方法的分析器。这样您的日志记录将为您提供功能列表。
答案 2 :(得分:0)
您还可以使用Visual Studio代码覆盖率(如果您的版本中提供)。
答案 3 :(得分:0)
代码合同可以在这里帮忙吗?如果您可以在这种情况下验证某些值的状态布尔测试,那么您是否能够确定代码路径?他们并没有大规模的自负。 http://research.microsoft.com/en-us/projects/contracts/