Как получить список типов, которые расширены методом расширения в ndepend cqlinq? Используя рефлексию для кода, это похоже на работу осла, где ndepend уже существует.Получение списка типов, которые выполняются методом расширения в cqlinq
ответ
Модель кода NDepend не имеет прямого способа разрешить тип параметра метода. Таким образом, мы можем найти удовлетворительный ответ с кодовым запросом, основанным на расширении имени форматирования строки, извлеченного из имени метода. Но этот запрос слишком сложный, и есть крайние случаи, когда он не будет работать должным образом (объясняется ниже).
Вот запрос кода, он работает быстро, даже на большой коду базовые благодаря использованию словаря:
//
// First let build dicoExtensionMethods
let dicoExtensionMethods =
(from m in Application.Methods
where m.IsExtensionMethod
// extract extended type simple name (with generic parameters like "IEnumerable<String>")
let beginIndex = m.Name.IndexOf("(") + 1
let endIndex = m.Name.IndexOf(',', beginIndex) > 0 ? m.Name.IndexOf(',', beginIndex) : m.Name.IndexOf(")", beginIndex)
let extendedTypeSimpleName1 = m.Name.Substring(beginIndex, endIndex - beginIndex)
// Take care of generic type first char, like "IEnumerable<"
let extendedTypeSimpleName2 = extendedTypeSimpleName1.IndexOf('<') == -1 ? extendedTypeSimpleName1 :
extendedTypeSimpleName1.Substring(0, extendedTypeSimpleName1.IndexOf('<') + 1)
select new { m, extendedTypeSimpleName2 })
.ToLookup(pair => pair.extendedTypeSimpleName2)
.ToDictionary(g => g.Key, g=> g.Select(p =>p.m))
//
// Second for each type get extension methods from dicoExtensionMethods
from t in Types
// Format type name like "IEnumerable<"
let typeName = !t.IsGeneric ? t.SimpleName : t.Name.Substring(0, t.Name.IndexOf('<') + 1)
where dicoExtensionMethods.ContainsKey(typeName)
let methods = dicoExtensionMethods[typeName]
select new { t, methods }
Как написано это сложный запрос из имени типа форматирования, и она отлично работает большую часть времени.
Однако, когда речь заходит о расширении общего типа, он говорит, например, что IEnumerable<T>
распространяется обоими способами, которые расширяют IEnumerable<String>
и IEnumerable<Int32>
. Это приемлемо, но это не на 100% правильно.
Кроме того, если вы расширяете несколько типов с одинаковым именем, но различной родовой арностью (как Func<T1,T2>
и Func<T1,T2,T3>
), то этот код запрос не будет работать должным образом.
То же самое, если вы продлеваете несколько типов с одинаковым именем, объявленным в разных сборках или пространстве имен (что в любом случае является запахом кода).
Надеюсь, это поможет!
Святой ад! Какой замечательный ответ спасибо, еще одна причина купить NDepend, спасибо – Arjang
Добро пожаловать! Я все еще немного разочарован объяснением недостатка, но в будущем это будет исправлено! По крайней мере, мы придумали правильный ответ на 99% случаев в реальном мире :) –
Я не хочу быть навязчивым, вы можете взглянуть на http://stackoverflow.com/questions/29481538/how-to-get -list-of-extension-methods-in-a-solution-or-project-in-vs2013, я считаю более простой вариант этого вопроса, и я очень счастлив, просто найдя методы расширения для решения. – Arjang