Статический анализ .NET-гарантированные вызовы функций в программе
есть ли способ узнать все вызовы функций, которые будут выполняться как часть программы в мире C#?
например, учитывая это:
static void Main(string[] args)
{
if (true)
{
CallTrueFunction();
}
else
{
CallFalseFunction();
}
}
могу ли я сказать через FxCop или какую-либо другую систему, чтобы узнать CallTrueFunction?
4 ответов
короткий ответ:нет.
немного более длинный ответ-нет,не для любой нетривиальной программы на любом языке программирования.
более подробный ответ заключается в том, что вы описываете проблемы остановки больше или меньше. Нет общего способа определить, какие методы достижимы, а какие нет, потому что для этого вам нужно будет решить проблему остановки.
представьте себе while
цикл и после цикла является единственным вызовом myfunc()
. Is myfunc()
называется? Вы не можете знать, потому что цикл может или не может завершиться. Возможно, цикл зависит от переменной, переданной в функцию. Возможно, это зависит от ввода от пользователя. В любом случае, если цикл завершается, то myfunc()
называется. Если цикл не завершается, то myfunc()
- это мертвый код, который никогда не будет вызван. Давайте просто скажем, что вы делаете while(Console.ReadLine() != "G") { }
. Ваша программа вызывает myfunc()
? Зависит от входных данных!
и подобно задаче остановки, вы можете построить тривиально маленькие программы, которые всегда дают правильный ответ, или создать чрезвычайно крошечные конечные машины, которые всегда дают правильный ответ. Но если вы затем возьмете свою программу статического анализа и запустите ее даже в умеренно небольшом приложении, количество комбинаций потенциальных состояний быстро превысит количество доступных атомов во Вселенной.
единственный способ узнать, будет ли ваша программа вызывать эту функцию или эту функцию запустить его и посмотреть, сработает ли. Затем вы можете сказать: "для ввода X, в среде Y, на CPU Z, в момент времени D, учитывая эти версии этих системных библиотек, в то время как система находилась под этой нагрузкой процессора, и это количество нагрузки ввода-вывода, и где вибрации земли не прерывали жесткий диск, и где космический луч не переворачивал никаких битов в памяти, моя программа называла подмножество G всех доступных функций F".
если какая-либо из этих переменных изменяется (вход является основным), тогда ваш предыдущий анализ неполон.
Примечание: даже невозможно сделать сильные гарантии о том, какие функции могут быть вызваны, потому что отражение может вызвать любую функцию, построив строку (так что вы даже не можете сканировать имена функций), или даже генерировать и вводить новые функции в вашу программу.
В зависимости от того, чего вы хотите достичь, один из возможных способов-подойти к вещам по-другому и отметить/удалить все, что не может быть достигнуто. С Resharper вы можете легко найти весь неиспользуемый код. Следуя вашему примеру, это будет означать:
else
{
CallFalseFunction();
}
как недостижимый код. И он предложит вам изменить:
if (true)
{
CallTrueFunction();
}
в:
CallTrueFunction();
после того, как вы очистили свой проект таким образом, все, что осталось, должно быть вызываемым через некоторый путь выполнения и все, что не зависит от условного параметра, должно быть вызвано (при условии, что программа не прерывается наполовину).
Это не поможет вам при попытке найти, какие методы вызываются из определенной точки входа в вашем приложении с определенными параметрами. Если это то, что вы ищете, возможно, вы можете попробовать использовать профилировщик, способный регистрировать каждый вызываемый метод. Таким образом, вы logging даст вам список функции.
может код контрактам помочь? Если вы можете проверить состояние определенных значений логического теста в этом случае, то вы сможете определить пути кода? Не массово au fait с ними. http://research.microsoft.com/en-us/projects/contracts/