Ndepend 为嵌套可见性细化CQLinq规则

Ndepend 为嵌套可见性细化CQLinq规则,ndepend,cqlinq,Ndepend,Cqlinq,我们有NDepend 5.4.1,我们希望修改对字段/类型/方法的查询,这些查询可能具有较低的可见性。我们希望查询在决定是否将其视为违规时考虑到封闭类的范围。 比如说, internal class X { public int A; public void B() { } public class C { // … } } 我们不希望A、B或C产生一个冲突,说它们中的任何一个都应该是内部的。另一方面,如果类X是公共的,并且A、B和C都没有在程序集之外

我们有NDepend 5.4.1,我们希望修改对字段/类型/方法的查询,这些查询可能具有较低的可见性。我们希望查询在决定是否将其视为违规时考虑到封闭类的范围。 比如说,

internal class X
{
   public int A;
   public void B() { }
   public class C
   {
      // …
   }
}
我们不希望A、B或C产生一个冲突,说它们中的任何一个都应该是内部的。另一方面,如果类X是公共的,并且A、B和C都没有在程序集之外使用,那么它们都应该生成冲突

为此,我在查询中添加了以下行:

 // consider visibility of enclosing class
 f.ParentType.Visibility < f.OptimalVisibility
<代码> /考虑封闭类的可见性 f、 ParentType.Visibility 因此,对于字段,新查询如下所示:

// <Name>Fields that could have a lower visibility</Name>
warnif count > 0 from f in JustMyCode.Fields where 
  f.Visibility != f.OptimalVisibility &&
 !f.HasAttribute("NDepend.Attributes.CannotDecreaseVisibilityAttribute".AllowNoMatch()) &&
 !f.HasAttribute("NDepend.Attributes.IsNotDeadCodeAttribute".AllowNoMatch()) &&
 // consider visibility of enclosing class
 f.ParentType.Visibility < f.OptimalVisibility

select new { f, 
             f.Visibility , 
             CouldBeDeclared = f.OptimalVisibility,
             f.MethodsUsingMe }
//可能具有较低可见性的字段
在JustMyCode.字段中从f开始的warnif计数>0,其中
f、 能见度!=f、 最佳可见度&&
!f、 HasAttribute(“NDepend.Attributes.CannotDecreaseVisibilityAttribute.AllowNoMatch())&&
!f、 HasAttribute(“NDepend.Attributes.IsNotDeadCodeAttribute.AllowNoMatch())&&
/考虑封闭类的可见性
f、 ParentType.Visibility
我以类似的方式更改了方法可见性和类型可见性的查询,但类型除外,我确保有一个封闭的父类型:

(t.ParentType == null || t.ParentType.Visibility < t.OptimalVisibility)
(t.ParentType==null | | t.ParentType.Visibility

乍一看,在运行了一些测试之后,这似乎是在做正确的事情。我的问题是,这是否会产生任何误报或遗漏任何违规行为,因为我不确定枚举可见性排序(比较)是否在所有情况下都正确。

以下是
NDepend.CodeModel.visibility
枚举声明:

   public enum Visibility {
      None = 0,
      Public = 1,
      ProtectedAndInternal = 2,
      ProtectedOrInternal = 3,
      Internal = 4,
      Protected = 5,
      Private = 6
   }
因此
x.ParentType.Visibility
意味着
x父类型的可见性比x最佳可见性的限制性要小得多

请注意,
Protected
的顺序比
Internal
更严格,后者不是
true
也不是
Internal
Protected
更严格。因此,我们必须在这两个可见性级别之间提供任意顺序

还请注意,方法/字段/嵌套类型可以在嵌套类型(递归)中声明,因此为了正确起见,我们需要收集所有outter类型的可见性

这两个事实让我想到,我们可以构建边缘案例,在这些案例中,您的规则将返回假阳性,但经过一点修补,我没有成功

我们的建议是查看您的代码库,了解自定义规则的行为,看看是否应该修改它们。如果它是好的,那么认为它是好的,直到你最终找到一个假阳性。

关于内部类型的成员应该被宣布为公共成员还是内部成员,存在着长期相关的争论。这两方面都有可靠的参数,我们编写代码规则的方式倾向于它应该声明为内部的一面,而您的更改倾向于它应该声明为公共的一面

以下是
NDepend.CodeModel.Visibility
枚举声明:

   public enum Visibility {
      None = 0,
      Public = 1,
      ProtectedAndInternal = 2,
      ProtectedOrInternal = 3,
      Internal = 4,
      Protected = 5,
      Private = 6
   }
因此
x.ParentType.Visibility
意味着
x父类型的可见性比x最佳可见性的限制性要小得多

请注意,
Protected
的顺序比
Internal
更严格,后者不是
true
也不是
Internal
Protected
更严格。因此,我们必须在这两个可见性级别之间提供任意顺序

还请注意,方法/字段/嵌套类型可以在嵌套类型(递归)中声明,因此为了正确起见,我们需要收集所有outter类型的可见性

这两个事实让我想到,我们可以构建边缘案例,在这些案例中,您的规则将返回假阳性,但经过一点修补,我没有成功

我们的建议是查看您的代码库,了解自定义规则的行为,看看是否应该修改它们。如果它是好的,那么认为它是好的,直到你最终找到一个假阳性。
关于内部类型的成员应该被宣布为公共成员还是内部成员,存在着长期相关的争论。这两方面都有可靠的参数,我们编写代码规则的方式倾向于它应该声明为内部的一面,而您的更改倾向于它应该声明为公共的一面