I am using reflection to analyse a method's exception handling blocks with the [ExceptionHandlingClauses]
property of the [MethodBody]
class. I could not figure out from MSDN Documentation how this collection behaves and how to interpret it. Let's say you want to assert that:
- a method contains exactly one try block.
- that single block contains exactly one
catch
clause. - that single block contains a
finally
clause.
Please try not to derive context out of the following code as it is too complex to explain here. This is just illustrative code and may be of bad design. Consider the following heirarchy:
// 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 { } }
I already know the following about these classes:
- Tier 1 base class has no implementation, thus no exception handling blocks.
- Tier 2 derived classes have no implementation, thus no exception handling blocks.
- Tier 3 derived classes have implementations of all virtual methods where all methods except
[OnTest]
do NOT contain exception handling blocks. - The
[OnTest]
method of all Tier 3 classes contains exactly one exception handling block and in some cases a nested block and/or a few[using]
statements.
I get all tier 3 classes from this assembly, iterate through each type, get the [MethodInfo]
objects for each method, get the [MethodBody]
object and inspect its [ExceptionHandlingClauses]
collection. The result is quite strange for the [OnTest]
method. The [ExceptionHandlingClauses]
collection shows up having anywhere between 0 to 6 clauses, each of which has a [Flag]
value of either [Catch]
or [Finally]
. There seems to be absolutely no correlation between the expected number of [catch/finally]
blocks and what this collection shows.
Sometimes, it evens shows two [Finally]
clauses in methods which do not even have a [try/catch]
block.
At first I thought this may have something to with inheritance but none of the base classes have implementations, let alone exception handling blocks.
Some guidance would be appreciated.