2009-11-04 4 views
3

У меня есть проект C#, для которого мне нужно найти все частные методы, которые не вызываются из какого-либо другого публичного метода прямо или косвенно.Статический анализ .net сборки

Кроме того, для каждого частного метода, который вызывается из общедоступного метода, мне нужно знать, какой публичный метод он есть. Затем я буду расценивать, действительно ли этот метод вызывается от клиента класса, и если нет, я смогу его удалить.

В прошлом я использовал код из Lutz Rorder, который является базой Reflector - он имел возможность анализировать код IL и давать объектную модель поверх нее. Я не могу найти этот код сейчас.

Любое предложение? Возможно, точка в этом коде Lutz Rorder?

Саар

ответ

1

Не уверен, что если она будет выполнять все эти потребности, но FXCop будет делать большинство из них для вас и поможет сделать всю серию стандартов кодирования, а также. Стоит обойти свой код C# в любом случае.

FXCop (MSDN)

+0

FxCop найти неиспользованные частные методы. Что касается тех, которые используются, щелкните правой кнопкой мыши метод и выберите «Найти все ссылки» в меню. – Pedro

2

Ну, единственный способ сделать это (по крайней мере, только одно, что я знаю ...) подразумевает использование коммерческой (но не так дорого) инструмента, а именно NDepend.

Среди других вещей вы можете написать SQL-подобные запросы против ваших скомпилированных сборок, что позволяет проводить очень мелкомасштабный анализ. Они называют это CQL, синтаксис является самообучающимся, а поддержка NDepend IntelliSense/автозаполнения, а также общая помощь/документация довольно хороши.

(AFAIK они также обеспечивают полноценный судебный процесс, если это поможет вам ...)

HTH!

0

Рефлектор все еще имеет эту функцию. Просто щелкните правой кнопкой мыши метод и нажмите «Анализ». Следуйте ссылкам в древовидной структуре.

Вы не говорите, нужно ли вам делать это в коде или просто «визуально».

Если необходимо для кода, я уверен, что вы можете использовать Reflector SDK.

0

Возможно, я смогу помочь вам с помощью редактора запросов в PowerCommands for Reflector addin (http://powercommands.codeplex.com) ... Я посмотрю, что я могу придумать сегодня вечером, а затем дайте вам знать завтра.

В противном случае вы также можете написать быстрое приложение с использованием CCI или Cecil, которые это сделают.

Запрос:

from a in AssemblyManager.Assemblies.Cast<IAssembly>() 
where a.Name != "mscorlib" 
    && !a.Name.Contains("System") 
from m in a.Modules.Cast<IModule>() 
from t in m.Types.Cast<ITypeDeclaration>() 
from mt in t.Methods.Cast<IMethodDeclaration>() 
where mt.Visibility == MethodVisibility.Public 
    && !mt.RuntimeSpecialName 
    && !mt.SpecialName 
    && mt.Body is IMethodBody 
from i in ((IMethodBody)mt.Body).Instructions.Cast<IInstruction>() 
where i != null 
    && i.Value != null 
    && i.Value is IMethodReference 
    && ((IMethodReference)i.Value).Resolve() != null 
    && ((IMethodReference)i.Value).Resolve().Visibility == MethodVisibility.Private 
select new { 
    CallingMethod=t.Namespace + "." + t.Name + "." + mt.Name, 
    PrivateReferencedMethod=((ITypeReference)((IMemberReference)((IMethodReference)i.Value).Resolve()).DeclaringType).Namespace + "." 
     + ((ITypeReference)((IMemberReference)((IMethodReference)i.Value).Resolve()).DeclaringType).Name + "." 
     + ((IMethodReference)i.Value).ToString() 
} 
+0

После прочтения вашего вопроса во второй раз - если вы заинтересованы в writihg утилите, которая делает то, что вы ищете, - тогда проверьте: http://ccimetadata.codeplex.com/ –

+0

Если вы хотите попробовать получить информацию от Reflector, вы можете использовать следующий запрос, чтобы получить все частные методы, вызываемые публичным методом. ПРИМЕЧАНИЕ. Предполагается, что все ваши зависимости загружены в Reflector уже ... если вы получите диалоговое окно с просьбой найти сборку, которую вам нужно нажать «Пропустить», или она убьет Reflector. –

+0

Я также добавил фильтрацию, чтобы игнорировать mscorlib или любую сборку системы, а также игнорировать специальные именованные методы (конструкторы и методы свойств). –

3

Вы должны проверить Nitriq Static Code Analysis for .Net - У них есть свободное сообщество издание и их полномасштабные лицензии довольно разумно.

3

Как указано Thomas, инструмент NDepend может помочь вам найти неиспользуемый код в базе данных .NET. Отказ от ответственности: Я являюсь одним из разработчиков этого инструмента.

NDepend предлагает написать Code Rule over LINQ Query (CQLinq).Вокруг 200 default code rules предлагается, 3 из них была посвящена неиспользованного/мертвый код обнаружения:

  • Potentially dead Types (следовательно, обнаружить неиспользованный класс, структура, интерфейс, делегат ...)
  • Potentially dead Methods (отсюда обнаружить неиспользуемый метод , т е р, свойство геттер/сеттер ...)
  • Potentially dead Fields

NDepend интегрирован в Visual Studio, таким образом, эти правила могут быть checked/browsed/edited right inside the IDE. Инструмент также может быть интегрирован в ваш процесс CI, и он может построить reports, который покажет нарушения правил и элементы кода.

Если вы нажмете эти 3 ссылки выше на исходный код этих правил, вы увидите, что те, которые относятся к типам и методам, немного сложны. Это связано с тем, что они обнаруживают не только неиспользуемые типы и методы, но и используемые типы и методы только по неиспользуемым мертвым типам и методам (рекурсивный).

Это статический анализ, следовательно, префикс Потенциально в названиях правил. Если элемент кода используется только через отражение, эти правила могут считать его неиспользованным, что не так.

В дополнение к использованию этих 3 правил я бы посоветовал измерить охват кода испытаниями и стремлением к полному охвату. Часто вы увидите, что код, который не может быть охвачен испытаниями, на самом деле является неиспользуемым/мертвым кодом, который можно безопасно отбросить. Это особенно полезно в сложных алгоритмах, когда неясно, доступна ли ветка кода или нет.


Кроме того, для каждого частного метода, который вызывается из открытого метода, мне нужно знать, какой публичный метод это.

Чтобы получить эту информацию, с CQLinq вам просто нужно написать:

from m in Application.Methods 
where m.IsPrivate 
let publicMethodsCallingMe = m.MethodsCallingMe.Where(m1 => m1.IsPublic) 
where publicMethodsCallingMe.Count() > 0 
select new { m, publicMethodsCallingMe } 

Результат запроса будет легко просматриваемый:

Browsing CQLinq query result

Смежные вопросы