リフレクションを使用して、メソッドの例外処理ブロックをクラスの[ExceptionHandlingClauses]
プロパティで分析しています。このコレクションがどのように動作し、どのように解釈するか、 MSDN ドキュメント[MethodBody]
からはわかりませんでした。それを主張したいとしましょう:
- メソッドには、try ブロックが 1 つだけ含まれています。
- その単一のブロックには、ちょうど 1 つの
catch
句が含まれます。 - その単一のブロックには
finally
句が含まれています。
ここで説明するには複雑すぎるため、次のコードからコンテキストを導き出さないようにしてください。これは単なる例示的なコードであり、設計が悪い可能性があります。次の階層を考えてみましょう。
// Tier 1. Base class.
namespace ProductName
{
// This is not an abstract class.
// These tier 1 class methods to not have implementations or exception handling blocks.
public class Template: System.IDisposable
{
public sealed void Launch () { this.OnLaunch(); }
public sealed void Simulate () { this.OnSimulate(); }
public sealed void Test () { this.OnTest(); }
public sealed void Submit () { this.OnSubmit(); }
public sealed void Exit () { this.OnExit(); }
protected virtual void OnLaunch () { }
protected virtual void OnSimulate () { }
protected virtual bool OnTest () { return (false); }
protected virtual void OnSubmit () { }
protected virtual void OnExit () { }
}
}
// Tier 2. Defines template platforms e.g. Access, Excel, etc.
// These tier 2 classes do not have implementations or exception handling blocks.
namespace ProductName.Access { public class Template: ProductName.Template { } }
namespace ProductName.Excel { public class Template: ProductName.Template { } }
namespace ProductName.Outlook { public class Template: ProductName.Template { } }
namespace ProductName.PowerPoint { public class Template: ProductName.Template { } }
namespace ProductName.Word { public class Template: ProductName.Template { } }
// Tier 3. Defines individual templates in each platform.
// Each platform will have hundreds of classes with a [Template_########] naming convention.
// Each class overrides all virtual methods with exactly one try/catch/finally block in OnTest and none in other methods.
namespace ProductName.Access.Templates { public class Template_00000001: ProductName.Access.Template { } }
namespace ProductName.Excel.Templates { public class Template_00000001: ProductName.Excel.Template { } }
namespace ProductName.Outlook.Templates { public class Template_00000001: ProductName.Outlook.Template { } }
namespace ProductName.PowerPoint.Templates { public class Template_00000001: ProductName.PowerPoint.Template { } }
namespace ProductName.Word.Templates { public class Template_00000001: ProductName.Word.Template { } }
私はこれらのクラスについて次のことをすでに知っています。
- Tier 1 基本クラスには実装がないため、例外処理ブロックはありません。
- 層 2 の派生クラスには実装がないため、例外処理ブロックはありません。
- 層 3 の派生クラスには、すべての仮想メソッドの実装があり
[OnTest]
、例外処理ブロックを除くすべてのメソッドには含まれません。 - すべての Tier 3 クラスの
[OnTest]
メソッドには、例外処理ブロックが 1 つだけ含まれており、場合によっては、ネストされたブロックやいくつかの[using]
ステートメントが含まれています。
このアセンブリから層 3 のすべてのクラスを取得し、各型を反復処理して、[MethodInfo]
各メソッドのオブジェクトを取得し、オブジェクトを取得してそのコレクション[MethodBody]
を調べます。[ExceptionHandlingClauses]
メソッドの結果は非常に奇妙です[OnTest]
。コレクションには0 ~ 6 個の節があり、それぞれが または のいずれかの値[ExceptionHandlingClauses]
を持っています。予想されるブロック数とこのコレクションが示すものとの間には、まったく相関関係がないようです。[Flag]
[Catch]
[Finally]
[catch/finally]
場合によっては、ブロック[Finally]
さえも持たないメソッドに 2 つの句が表示されることがあります。[try/catch]
最初は、これは継承と関係があるのではないかと思っていましたが、例外処理ブロックは言うまでもなく、どの基本クラスにも実装がありません。
いくつかのガイダンスをいただければ幸いです。