我使用反射来分析具有[ExceptionHandlingClauses]
类的[MethodBody]
属性的方法的异常处理块。我无法从MSDN Documentation中弄清楚这个集合的行为以及如何解释它。假设你想断言:
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 { } }
我已经知道以下关于这些类的内容:
[OnTest]
之外的所有方法都不包含异常处理块。[OnTest]
方法只包含一个异常处理块,在某些情况下还包含嵌套块和/或一些[using]
语句。我从这个程序集中获取所有第3层类,遍历每个类型,获取每个方法的[MethodInfo]
个对象,获取[MethodBody]
对象并检查其[ExceptionHandlingClauses]
集合。 [OnTest]
方法的结果非常奇怪。 [ExceptionHandlingClauses]
集合显示在0到6个子句之间,每个子句的[Flag]
值为[Catch]
或[Finally]
。预期的[catch/finally]
块数与此集合显示的内容之间似乎完全没有关联。
有时,它甚至会在方法中显示两个[Finally]
子句,这些子句甚至没有[try/catch]
块。
起初我认为这可能与继承有关,但没有基类具有实现,更不用说异常处理块了。
一些指导意见将不胜感激。
答案 0 :(得分:3)
ExceptionHandlingClauses
属性提供有关已编译字节码中的异常处理子句的信息。字节码中异常处理块的语义由ECMA-335标准控制,而不是由ECMA-334(C#语言标准)控制。 C#中的异常处理块的规则与字节码强加的规则不同,因此编译器有时会以产生看似奇怪的异常处理块的方式编译代码,但实际上根据原始C#代码产生正确的运行时语义
在其他情况下,C#为字节码原语不支持的功能提供“语法糖”。例如,C#中的using
和lock
语句都是通过编译到try
/ finally
块来实现的,这些块将包含在ExceptionHandlingClauses
属性中