我们有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
因此对于字段,新查询如下所示:
// <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 }
我以类似的方式更改了方法可见性和类型可见性的查询,除了类型我确保有一个封闭的父类型:
(t.ParentType == null || t.ParentType.Visibility < t.OptimalVisibility)
乍一看,经过一些测试后,这似乎做得对了。我的问题是,这是否会产生任何误报或遗漏任何违规行为,因为我不确定枚举可见性排序(比较)是否会在所有情况下做正确的事情。
答案 0 :(得分:0)
这是NDepend.CodeModel.Visibility
枚举声明:
public enum Visibility {
None = 0,
Public = 1,
ProtectedAndInternal = 2,
ProtectedOrInternal = 3,
Internal = 4,
Protected = 5,
Private = 6
}
因此x.ParentType.Visibility < x.OptimalVisibility
表示x parent type visibility is strictly less restrictive than x optimal visibility
。
请注意,Protected
的排序限制比Internal
更严格,true
Internal
Protected
的限制性比{{1}}更严格。所以我们必须在这两个可见性级别之间提供任意顺序。
另请注意,方法/字段/嵌套类型可以以嵌套类型(递归)声明,因此为了正确起见,我们需要收集所有外部类型的可见性。
这两个事实让我觉得我们可以构建一些边缘情况,你的规则会返回误报,但经过修改后我没有成功。
我们的建议是查看您的代码库,以了解自定义规则的行为,以确定是否应该修改它们。如果没问题,那么在你最终发现误报之前,请考虑它是好的。
关于Eric Lippert blog关于内部类型的成员是否应被宣布为公开或内部的问题,存在长期相关的争论。双方都有坚实的论据,而且我们的代码规则的编写方式有利于方它应该被声明为内部,而你的更改有利于方它应该被声明为public 。