3

VisualStudio のよくある問題は、プロパティ ゲッターの不思議な呼び出しです。これらに副作用がある場合 (最も一般的な形式はif (foo == null) foo = new foo(); return foo;)、デバッガーの [ローカル] ウィンドウと [ウォッチ] ウィンドウがブレーク ポイントに到達することなくプロパティを呼び出すという事実により、デバッグ時に予期しない影響が生じる可能性があります。

これには簡単な解決策があります。属性でプロパティにタグを付けるだけです

        [DebuggerBrowsable(DebuggerBrowsableState.Never)]

では、大規模なコード ベースで副作用が発生する可能性のあるゲッターを見つけるにはどうすればよいでしょうか。

NDependは、この種のツールとして最適です。その CQL 言語を使用すると、たとえば、含まれているインスタンスの状態を直接変更するすべてのプロパティを見つけることができます。

         SELECT METHODS FROM ASSEMBLIES "FOO" 
         WHERE IsPropertyGetter AND ChangesObjectState 

これは、フィールドを直接変更する getter のみを検索しますInitialize()。メソッドを呼び出すなどして間接的に変更する getter を検索するにはどうすればよいですか?

4

1 に答える 1

2

Joel さん、これはLINQ 機能(CQLinq)によるコード クエリのおかげで可能になりました。プロパティ ゲッターの深い可変性を検出する CQLinq クエリを次に示します。可変性を引き起こすゲッターごとに、コード クエリは割り当てられたフィールドのセットを示します。

// Restrict the iteration only on property getters
// that are changing states or that call a method that changes state
let propertyGetters = Application.Methods.Where(m => m.IsPropertyGetter)

let methodsThatChangeState = 
  Application.Methods.Where(m => m.ChangesObjectState || m.ChangesTypeState)

from m in propertyGetters.DepthOfIsUsingAny(methodsThatChangeState).DefinitionDomain
          .Union(propertyGetters.Intersect(methodsThatChangeState))

// Find all methods called directly or indirectly by the property getter
let methodsCalledIndirectly = 
        m.MethodsCalled.FillIterative(
           methods => methods.SelectMany(m1 => m1.MethodsCalled))
        .DefinitionDomain
        .Union(m.ToEnumerable())

// Gather all field assigned that are not generated by the compiler
let fieldsAssigned = methodsCalledIndirectly
                     .SelectMany(m1 => m1.FieldsAssigned)
                     .Where(f => !f.IsGeneratedByCompiler)

where fieldsAssigned.Any()
orderby fieldsAssigned.Count() descending 
select new { m, fieldsAssigned }

このクエリは複雑です。これは主に、状態を変更するゲッター、または状態を変更するメソッド( DepthOfIsUsingAny()への呼び出し) を直接的または間接的に呼び出すゲッターのみを保持するように最適化したためです。

次に、この getter ごとに、( FillIterative()の呼び出しにより) 直接的または間接的に呼び出されるすべてのメソッドのセットを構築し、このすべてのメソッドによって割り当てられたすべてのフィールドを収集します。

具体的には、クエリの結果は次のようになります。

ここに画像の説明を入力

于 2010-07-21T14:50:30.330 に答える