C#如何在最新版本2018.1.1中使用ndepend获取项目/解决方案中的循环方法

时间:2018-06-14 15:35:52

标签: c# .net ndepend

我在NDepend版本2018.1.1中尝试了此代码,并对堆栈溢出中发布的原始代码进行了一些更改。它是为了获得具有循环依赖关系的方法(即相互调用并形成循环/循环代码)

但是这个代码似乎不适用于最新的nDepend。

注意:与StackOverflow上的其他代码的唯一区别在于,根据版本2018.1.1的要求,此代码具有此功能;

let cycle = ExtensionMethodsEnumerable.Append(usersAndUsed,suspect)

守则.....

    // <Name>Avoid methods of a type to be in cycles</Name>
warnif count > 0


from t in Application.Types
                 .Where(t => t.ContainsMethodDependencyCycle != null && 
                             t.ContainsMethodDependencyCycle.Value)

// Optimization: restreint methods set
// A method involved in a cycle necessarily have a null Level.
let methodsSuspect = t.Methods.Where(m => m.Level == null)

// hashset is used to avoid iterating again on methods already caught in a cycle.
let hashset = new HashSet<IMethod>()


from suspect in methodsSuspect
   // By commenting this line, the query matches all methods involved in a cycle.
   where !hashset.Contains(suspect)

   // Define 2 code metrics
   // - Methods depth of is using indirectly the suspect method.
   // - Methods depth of is used by the suspect method indirectly.
   // Note: for direct usage the depth is equal to 1.
   let methodsUserDepth = methodsSuspect.DepthOfIsUsing(suspect)
   let methodsUsedDepth = methodsSuspect.DepthOfIsUsedBy(suspect)

   // Select methods that are both using and used by methodSuspect
   let usersAndUsed = from n in methodsSuspect where
                         methodsUserDepth[n] > 0 && 
                         methodsUsedDepth[n] > 0 
                      select n

   where usersAndUsed.Count() > 0

   // Here we've found method(s) both using and used by the suspect method.
   // A cycle involving the suspect method is found!
   let cycle = ExtensionMethodsEnumerable.Append(usersAndUsed,suspect)

   // Fill hashset with methods in the cycle.
   // .ToArray() is needed to force the iterating process.
   let unused1 = (from n in cycle let unused2 = hashset.Add(n) select n).ToArray()

select new { suspect, cycle }

1 个答案:

答案 0 :(得分:0)

提供的查询在我的结​​束时可以正常工作,以查找类型内的方法循环。

对于方法的一般循环(无论其父类型),只需以这种方式修改查询的开头。

//from t in Application.Types
//                 .Where(t => t.ContainsMethodDependencyCycle != null && 
//                             t.ContainsMethodDependencyCycle.Value)

// Optimization: restreint methods set
// A method involved in a cycle necessarily have a null Level.
let methodsSuspect = Application.Methods.Where(m => m.Level == null)

同样增加NDepend&gt;选项&gt; CQLinq查询执行超时到60秒,因为查询在大型代码库上运行速度很慢,且遍历所有图形。

请记住,循环不一定像A调用B调用C调用A那样简单。循环是一组方法,其中从任何方法,循环中的任何其他方法都有路径。它可能非常复杂,如: Method cycle

要显示方法循环,​​只需将其导出到代码图:

Export cycle methods to the graph

通常要打破周期,首先要打破相互依赖关系,例如A调用B和B调用A。

方法循环不一定是代码气味,例如许多GoF设计模式依赖于方法循环。