1

NDepend 5.4.1 があり、可視性が低くなる可能性のあるフィールド/タイプ/メソッドのクエリを変更したいと考えています。クエリを違反と見なすかどうかを決定する際に、囲んでいるクラスのスコープを考慮に入れる必要があります。

例えば、

internal class X
{
   public int A;
   public void B() { }
   public class C
   {
      // …
   }
}

A、B、または C が、いずれかを内部にする必要があるという違反を生成することは望ましくありません。一方、クラス X が public で、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)

一見すると、いくつかのテストを実行した後、これは正しいことをしているように見えます。私の質問は、これが誤検知を生成するか、違反を見逃すかどうかです。列挙型の可視性の順序付け (比較) がすべての場合に正しいことを行うかどうかわからないためです。

4

1 に答える 1

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ではありません。そのため、これら 2 つの可視性レベルの間で任意の順序を指定する必要がありました。trueInternalProtected

メソッド/フィールド/ネストされた型はネストされた型 (再帰的) で宣言できることにも注意してください。正しくするには、すべての外側の型の可視性を収集する必要があります。

これらの 2 つの事実から、ルールが誤検出を返すエッジ ケースを構築できると思いましたが、少しいじってみたところ、成功しませんでした。

私たちがアドバイスするのは、カスタム ルールがどのように動作するかコード ベースを調べて、それらを変更する必要があるかどうかを確認することです。問題がない場合は、最終的に誤検知が見つかるまで問題ないと考えてください。


内部型のメンバーを public または internal と宣言する必要があるかどうかについて、 Eric Lippert ブログで長い間議論されています。どちらの側にも確固たる議論があり、私たちのコードルールの書き方はinternal として宣言されるべき側を支持し、あなたの変更は public として宣言されるべき側を支持します。

于 2015-06-03T06:03:44.417 に答える