5

この質問が探しているクエリは、IDisposable の実装に関するすべての小さな問題を見つけるのに十分ではないことを認識していますが、早期警告はすべて重要なので、取得できるものを取り上げます。

IDisposable を実装していないが、実装しているフィールドが 1 つ以上あるすべてのクラスをリストする NDepend の CQL クエリを誰かが思いついたかどうかを知りたいです。バグ (つまり、誰かが IDisposable 実装のフィールド タイプをチェックするのを忘れた)、またはコードの進化 (つまり、どこかのフィールドで使用されるクラスに IDisposable が追加される) によって、クラスがこのクエリの結果リストに含まれる可能性があります。すべての使用状況が更新されることなく後日)。

IDisposable を実装していないすべてのクラスを検索する単純なクエリは次のとおりです。

SELECT TYPES WHERE !Implement "System.IDisposable"

ただし、これはもちろん、クラスが上記のルールの IDisposable を実装する必要があるかどうかをチェックしません。

誰かそのようなクエリを持っていますか?私はまだCQLに慣れてきているので、この部分はわかりません。

4

1 に答える 1

8

Lasse さん、CQLinq (Code Rule over LINQ) 機能のおかげで、IDisposable を実装する必要がある型に一致することが可能になりました。実際には、関連する 2 つのデフォルト ルールが提供されており、独自の関連ルールを簡単に作成できます。


// <Name>Types with disposable instance fields must be disposable</Name>
warnif count > 0

let iDisposable = ThirdParty.Types.WithFullName("System.IDisposable").FirstOrDefault() 
where iDisposable != null // iDisposable can be null if the code base doesn't use at all System.IDisposable

from t in Application.Types where 
   !t.Implement(iDisposable) && 
   !t.IsGeneratedByCompiler 

let instanceFieldsDisposable = 
    t.InstanceFields.Where(f => f.FieldType != null &&
                                f.FieldType.Implement(iDisposable))

where instanceFieldsDisposable.Count() > 0
select new { t, instanceFieldsDisposable }

// <Name>Disposable types with unmanaged resources should declare finalizer</Name>
// warnif count > 0
let iDisposable = ThirdParty.Types.WithFullName("System.IDisposable").SingleOrDefault()
where iDisposable != null // iDisposable can be null if the code base deosn't use at all System.IDisposable

let disposableTypes = Application.Types.ThatImplement(iDisposable)
let unmanagedResourcesFields = disposableTypes.ChildFields().Where(f => 
   !f.IsStatic && 
    f.FieldType != null && 
    f.FieldType.FullName.EqualsAny("System.IntPtr","System.UIntPtr","System.Runtime.InteropServices.HandleRef")).ToHashSet()
let disposableTypesWithUnmanagedResource = unmanagedResourcesFields.ParentTypes()

from t in disposableTypesWithUnmanagedResource
where !t.HasFinalizer
let unmanagedResourcesTypeFields = unmanagedResourcesFields.Intersect(t.InstanceFields)
select new { t, unmanagedResourcesTypeFields }
于 2008-11-24T12:59:15.723 に答える