基本クラスに何千もの派生クラスがある大規模なプロジェクトに取り組んでいます (複数の開発者がそれらに取り組んでいます)。各クラスは、一連のメソッドをオーバーライドすることが期待されています。私は最初に、受け入れ可能なパターンに準拠したコード テンプレートを使用して、これらの数千のクラス ファイルを生成しました。私は現在、開発者がこのパターンから逸脱していないことを確認するために単体テストを作成しています。生成されたクラスのサンプルを次に示します。
// Base class.
public abstract partial class BaseClass
{
protected abstract bool OnTest ();
}
// Derived class. DO NOT CHANGE THE CLASS NAME!
public sealed partial class DerivedClass_00000001: BaseClass
{
/// <summary>
/// Do not modify the code template in any way.
/// Write code only in the try and finally blocks in this method.
/// </summary>
protected override void OnTest ()
{
bool result = false;
ComObject com = null;
// Declare ALL value and reference type variables here. NOWHERE ELSE!
// Variables that would otherwise be narrowly scoped should also be declared here.
// Initialize all reference types to [null]. [object o;] does not conform. [object o = null;] conforms.
// Initialize all value types to their default values. [int x;] does not conform. [int x = 0;] conforms.
try
{
com = new ComObject();
// Process COM objects here.
// Do NOT return out of this function yourself!
}
finally
{
// Release all COM objects.
System.Runtime.InteropServices.Marshal.ReleaseComObject(com);
// Set all COM objects to [null].
// The base class will take care of explicit garbage collection.
com = null;
}
return (result);
}
}
単体テストでは、リフレクションを介して次のことを確認できました。
- このクラスは [BaseClass] から派生し、インターフェイスを実装していません。
- クラス名はパターンに準拠しています。
- catch ブロックはフィルター処理されていません。
- 他の catch ブロックは追加されていません。
- クラス レベルのフィールドまたはプロパティが宣言されていません。
- すべてのメソッド値型変数は、宣言時に手動で初期化されています。
- 派生クラスには他のメソッドは追加されていません。
上記はリフレクションを介して簡単に実現できますが、次のリストを主張するのに苦労しています。
- catch ブロックは、キャッチした例外をラップしたり他の例外をスローしたりするのではなく、再スローします。
- 最後の
[return (result);]
行は変更されておらず、他の[return (whatever);]
呼び出しは追加されていません。これを達成する方法がわかりません。 - IDisposable を実装するすべての参照型が破棄されていることを確認します。
- [System.__ComObject] 型のすべての参照型が手動で逆参照され、finally ブロックで [null] に設定されていることを確認します。
ソースコードを解析することを考えましたが、絶対に必要でない限り、その解決策は好きではありません。これは厄介で、式ツリーがない限り、成功を保証することはほとんど不可能です。
ヒントをいただければ幸いです。